PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****

1057 Stack (30 分)

Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (-th smallest element if N is even, or (-th if N is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤). Then N lines follow, each contains a command in one of the following 3 formats:

Push key
Pop
PeekMedian

where key is a positive integer no more than 1.

Output Specification:

For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print Invalid instead.

Sample Input:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

Sample Output:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

题目大意:现请你实现一种特殊的堆栈,它多了一种操作叫“查中值”,即返回堆栈中所有元素的中值。对于N个元素,若N是偶数,则中值定义为第N/2个最小元;若N是奇数,则中值定义为第(N+1)/2个最小元。
分析:用排序查询的方法会超时~~用树状数组,即求第k = (s.size() + 1) / 2大的数。查询小于等于x的数的个数是否等于k的时候用二分法更快~

AC代码:

#include<iostream>
#include<stack>
#define lowbit(i) ((i) & (-i))
const int maxn=100010;
using namespace std;
int c[maxn];
stack<int>s;
void update(int x, int v) {
    for(int i = x; i < maxn; i += lowbit(i))
        c[i] += v;//值为i的数出现并更新与其相关的数
}
int getsum(int x) {
    int sum = 0;
    for(int i = x; i >= 1; i -= lowbit(i))
        sum += c[i];
    return sum;
}
void PeekMedian() {//查询小于等于x的数的个数是否等于k的时候用二分法更快~
    int left = 1, right = maxn, mid, k = (s.size() + 1) / 2;
    while(left < right) {
        mid = (left + right) / 2;
        if(getsum(mid) >= k)//每次用getsum(i)求得前i个数中实际出现了几个数,与中位数k比较即可
            right = mid;
        else
            left = mid + 1;
    }
    printf("%d\n", left);
}
int main() {
    int n, temp;
    scanf("%d", &n);
    char str[15];
    for(int i = 0; i < n; i++) {
        scanf("%s", str);
        if(str[1] == ‘u‘) {
            scanf("%d", &temp);
            s.push(temp);
            update(temp, 1);
        } else if(str[1] == ‘o‘) {
            if(!s.empty()) {
                update(s.top(), -1);
                printf("%d\n", s.top());
                s.pop();
            } else {
                printf("Invalid\n");
            }
        } else {
            if(!s.empty())
                PeekMedian();
            else
                printf("Invalid\n");
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/caiyishuai/p/11557816.html

时间: 2024-10-10 07:25:17

PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****的相关文章

PAT甲级1057 Stack【树状数组】【二分】

题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592 题意:对一个栈进行push, pop和找中位数三种操作. 思路: 好久没写题.感觉傻逼题写多了稍微有点数据结构的都不会写了. pop和push操作就不说了. 找中位数的话就二分去找某一个数前面一共有多少小于他的数,找到那个小于他的数刚好等于一半的. 找的过程中要用到前缀和,所以自然而然就应该上树状数组. 要注意树状数组的界应该是1e5而

PAT 甲级 1057 Stack

https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592 Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element o

hdu 4267/poj 3468 A Simple Problem with Integers (分状态的树状数组)

A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4283    Accepted Submission(s): 1334 Problem Description Let A1, A2, ... , AN be N elements. You need to deal with

PAT (Advanced Level) 1057. Stack (30)

树状数组+二分. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<map> #include<queue> #include<string> #include<stack> #include<vector> using namespace

PAT 1057. Stack (30)

题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1057 用树状数组和二分搜索解决,对于这种对时间复杂度要求高的题目,用C的输入输出显然更好 #include <cstdio> #include <string> #include <vector> #include <stack> using namespace std; const int NUM=100001; struct TreeArray {

PAT甲题题解-1057. Stack (30)-树状数组

不懂树状数组的童鞋,正好可以通过这道题学习一下树状数组~~百度有很多教程的,我就不赘述了 题意:有三种操作,分别是1.Push key:将key压入stack2.Pop:将栈顶元素取出栈3.PeekMedian:返回stack中第(n+1)/2个小的数 建立一个栈来模拟push和pop,另外还需要树状数组,来统计栈中<=某个数的总个数不了解树状数组的建议学习一下,很有用的.树状数组为c,有个虚拟的a数组,a[i]表示i出现的次数sum(i)就是统计a[1]~a[i]的和,即1~i出现的次数当我要

1057. Stack (30) - 树状数组

题目例如以下: Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are

PAT-1057. Stack (30)--树状数组

今天新学了一个知识,叫做线状数组,主要应用领域 1,数据频繁更新 2,求解某一段区间的和 以上产景情况下可以使用线状数组,更新某一个数据和求某一段时间之和时间复杂度都是Log(N) {常规情况是O(1)和O(N)} 线状数组和RMQ差不多,都可以再Log(N)时间复杂度内求解某一段区间的长度,线状数组额实现方式更为简单,更为方便 以下可以当做线段树的模板 主要函数有lowbit给定制定数字二进制下在末尾为0的个数. Update更新某一节点的值. getsum求解某一区间的值 Update是从叶

hdu 5314 Happy King 树点分冶 树状数组

Happy King Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 434    Accepted Submission(s): 79 Problem Description There are n cities and n?1 roads in Byteland, and they form a tree. The citie