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 }

转载于:https://www.cnblogs.com/barrier/p/5545927.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值