L3-002. 堆栈

L3-002. 堆栈

题目链接:https://www.patest.cn/contests/gplt/L3-002

线段树

可以用一个数组a[i]维护栈内数字为i的个数,若[0,K]中有n/2个数,即有n/2个比K小的数,则K为中位数。

线段树的数据修改和查询都是O(lgn)的,此题只需维护各个区间内的数的个数即可。

代码如下:

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<stack>
 4 #define N 100001
 5 #define lson l,m,n<<1
 6 #define rson m+1,r,n<<1|1
 7 using namespace std;
 8 stack<int>pq;
 9 int st[N<<2];
10 void build(int l,int r,int n,int key);
11 void change(int l,int r,int n,int key);
12 void updata(int n);
13 int query(int l,int r,int n,int key);
14 int main(void){
15     freopen("in.txt","r",stdin);
16     int n,key;
17     char s[15];
18     scanf("%d",&n);
19     while(n--){
20         scanf("%s",s);
21         switch(s[1]){
22     case 'o':
23         if(pq.empty())printf("Invalid\n");
24         else{
25             key=pq.top();
26             printf("%d\n",key);
27             pq.pop();
28             change(1,100000,1,key);
29         }
30         break;
31     case 'u':
32         scanf("%d",&key);
33         pq.push(key);
34         build(1,100000,1,key);
35         break;
36     case 'e':
37         if(pq.empty())printf("Invalid\n");
38         else{
39             key=pq.size()+1;
40             key>>=1;
41             printf("%d\n",query(1,100000,1,key));
42         }
43         break;
44     }
45     }
46     return 0;
47 }
48 void build(int l,int r,int n,int key){
49     if(l>=r){
50         st[n]++;
51         return;
52     }
53     int m=(l+r)/2;
54     if(key<=m)build(lson,key);
55     else build(rson,key);
56     updata(n);
57 }
58 void change(int l,int r,int n,int key){
59     if(l==r){
60         st[n]--;
61         return;
62     }
63     int m=(l+r)/2;
64     if(key<=m)change(lson,key);
65     else change(rson,key);
66     updata(n);
67 }
68 void updata(int n){
69     st[n]=st[n<<1]+st[n<<1|1];
70 }
71 int query(int l,int r,int n,int key){
72     if(l==r)return l;
73     int m=(l+r)/2;
74     if(key<=st[n<<1])return query(lson,key);
75     else return query(rson,key-st[n<<1]);
76 }
posted @ 2016-05-31 15:11  barriery  阅读(535)  评论(0编辑  收藏  举报