PAT (Advanced Level) 1057 Stack

题解

  第一种方法:令数组tree[]记录栈中的元素,栈中的数值 x 的个数为 tree[x] 。树状数组维护tree[],然后二分查找。

    第二种方法:利用分块,以一定长度区间为单位,记录栈中数值的个数,然后暴力查找。

代码

//树状数组 + 二分
#include
using namespace std;
const int maxn=100010;
int tree[maxn];
stack<int> sta;
void update(int p,int w);
int sum(int p);
int main()
{
    int n,w,left,right,mid,k;
    string op;
    scanf("%d",&n);
    while(n--)
    {
        cin>>op;
        if(op[1]=='u')
        {
            scanf("%d",&w);
            sta.push(w);
            update(w,1);
        }
        else 
        {
            if(sta.size()<1)    printf("Invalid\n");
            else if(op[1]=='o')
            {
                printf("%d\n",sta.top());
                update(sta.top(),-1);
                sta.pop();
            }
            else
            {
                left=0;right=maxn;k=(sta.size()+1)/2;
                while(left<=right)
                {
                    mid=(left+right)/2;
                    if(sum(mid)>=k) right=mid-1; 
                    else    left=mid+1;
                }
                printf("%d\n",left);
            }
        }
    }
    system("pause");
    return 0;
}
void update(int p,int w)
{
    for(;pp))
        tree[p]+=w;
}
int sum(int p)
{
    int ans=0;
    for(;p>0;p -= p&(-p))
        ans+=tree[p];
    return ans;
}
//分块
#include
using namespace std;
const int maxn=100010,block_size=367;
int cnt[maxn],block[280];
stack<int> sta;
void PUSH_POP(int index,int v);
int Find(int k);
int main()
{
    int n,w;
    string op;
    scanf("%d",&n);
    while(n--)
    {
        cin>>op;
        if(op[1]=='u')
        {
            scanf("%d",&w);
            sta.push(w);
            PUSH_POP(w,1);
        }
        else 
        {
            if(sta.size()<1)    printf("Invalid\n");
            else if(op[1]=='o')
            {
                printf("%d\n",sta.top());
                PUSH_POP(sta.top(),-1);
                sta.pop();
            }
            else  printf("%d\n",Find((sta.size()+1)/2));
        }
    }
    system("pause");
    return 0;
}
void PUSH_POP(int index,int v)
{
  cnt[index]+=v;
  block[index/block_size]+=v;
}
int Find(int k)
{
  int sum=0,i=0,index;
  while(sum + block[i] < k)
    sum+=block[i++];
  index=block_size*i;
  while(1)
  {
    if(sum + cnt[index] >= k) return index;
    else sum+=cnt[index],index++;
  }
}

你可能感兴趣的:(PAT (Advanced Level) 1057 Stack)