L3-002 特殊堆栈 (30分) 权值线段树求第k大

堆栈是一种经典的后进先出的线性结构,相关的操作主要有“入栈”(在堆栈顶插入一个元素)和“出栈”(将栈顶元素返回并从堆栈中删除)。本题要求你实现另一个附加的操作:“取中值”——即返回所有堆栈中元素键值的中值。给定 N 个元素,如果 N 是偶数,则中值定义为第 N/2 小元;若是奇数,则为第 (N+1)/2 小元。

输入格式:

输入的第一行是正整数 N(≤)。随后 N 行,每行给出一句指令,为以下 3 种之一:

Push key
Pop
PeekMedian
 

其中 key 是不超过 1 的正整数;Push 表示“入栈”;Pop 表示“出栈”;PeekMedian 表示“取中值”。

输出格式:

对每个 Push 操作,将 key 插入堆栈,无需输出;对每个 Pop 或 PeekMedian 操作,在一行中输出相应的返回值。若操作非法,则对应输出 Invalid

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 string tmp;
 5 stack<int>S;
 6 struct node
 7 {
 8     int ln,rn;
 9     int sum;
10 }tree[maxn<<4];
11 void build(int l,int r,int root)
12 {
13     tree[root].ln=l;tree[root].rn=r;tree[root].sum=0;
14     if(l==r){
15         return ;
16     }
17     int mid=l+r>>1;
18     build(l,mid,root<<1);
19     build(mid+1,r,root<<1|1);
20 }
21 void update(int pos,int val,int root)
22 {
23     int l=tree[root].ln;
24     int r=tree[root].rn;
25    // printf("haha: %d %d\n",l,r);
26     if(l==r){
27    //     printf("l:%d\n",l);
28         tree[root].sum+=val;
29         return;
30     }
31     int mid=l+r>>1;
32     if(pos<=mid) update(pos,val,root<<1);
33     else update(pos,val,root<<1|1);
34     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
35 }
36 int query(int root,int k)
37 {
38     int l=tree[root].ln;
39     int r=tree[root].rn;
40     if(l==r) return l;
41     int ans;
42     if(tree[root<<1].sum>=k) ans=query(root<<1,k);
43     else ans=query(root<<1|1,k-tree[root<<1].sum);
44     return ans;
45 }
46 int main()
47 {
48     build(1,maxn-10,1);
49     int n;
50     scanf("%d",&n);
51     for(int i=1;i<=n;i++){
52         cin>>tmp;
53         if(tmp=="Push"){
54             int val;
55             scanf("%d",&val);
56             S.push(val);
57             update(val,1,1);
58         }
59         else if(tmp=="PeekMedian"){
60             if(S.size()==0) printf("Invalid\n");
61             else{
62                 int k=(S.size()+1)/2;
63                 printf("%d\n",query(1,k));
64             }
65         }
66         else if(tmp=="Pop"){
67             if(S.size()==0) printf("Invalid\n");
68             else{
69                 int val=S.top();
70                 S.pop();
71                 printf("%d\n",val);
72                 update(val,-1,1);
73             }
74         }
75     }
76 }

 

posted @ 2020-11-25 16:42  古比  阅读(154)  评论(0编辑  收藏  举报