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 std;

const int maxn=100000+10;
int n;
int c[maxn];
stack<int>S;

int lowbit(int x){
    return x&(-x);
}

int getsum(int pos)
{
    int res=0;
    while(pos>0)
    {
        res=res+c[pos];
        pos=pos-lowbit(pos);
    }
    return res;
}

void update(int pos,int val)
{
    while(pos<=100000)
    {
        c[pos]=c[pos]+val;
        pos=pos+lowbit(pos);
    }
}

int main()
{
    while(!S.empty()) S.pop();
    memset(c,0,sizeof c);
    scanf("%d",&n);
    int sz=0;
    for(int i=1;i<=n;i++)
    {
        char op[15]; scanf("%s",op);
        if(strcmp(op,"Pop")==0)
        {
            if(sz==0) printf("Invalid
");
            else
            {
                sz--;
                printf("%d
",S.top());
                update(S.top(),-1);
                S.pop();
            }
        }
        else if(strcmp(op,"PeekMedian")==0)
        {
            if(sz==0) printf("Invalid
");
            else
            {
                int l=1,r=100000;
                int ans;
                while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(getsum(mid)>=(sz+1)/2)
                    {
                        ans=mid;
                        r=mid-1;
                    }
                    else l=mid+1;
                }
                printf("%d
",ans);
            }
        }
        else
        {
            int num; scanf("%d",&num);
            update(num,1);
            sz++;
            S.push(num);
        }
    }
    return 0;
}