L3-2. 堆栈(线段树单点更新)
来源:互联网 发布:神马快递打印软件 编辑:程序博客网 时间:2024/05/20 09:23
题目链接:https://www.patest.cn/contests/gplt/L3-2
思路分析:本题可以用一句话描述,就是求堆栈的中位数。堆栈是可以用数组模拟实现,可以用一个栈顶和栈底指针来实现数组模拟堆栈,分别用top和bottom。初始时,top=0,bottom=0,出栈的时候bottom++,进栈的时候top++。可以发现,栈中的所有元素恰好对应到数组里一段下标连续的子数组中。那么原问题就可以转化成求数组的中位数了,问题想到这里就很容易解决了,中位数即第n/2大的数,故可以用区间第K大的算法解决,但是这里出栈入栈涉及到更新,并非一般的静态区间第K大(只有询问没有修改的区间第K大),而是动态区间第K大。然后套用模板解决之。
细想之后,总感觉用区间第K大解决这个问题有点大材小用了,结合题目所给数据大小的限定,由于所给的数是0~10^5之间的数,而且查的又是整个区间的第n/2大的数,那么可以考虑建一棵维护区间里的数出现的次数的线段树。例如,区间[1,10]维护的是1,2,3,4,5,6,7,8,910总共出现多少次。
那么利用线段树单点更新即可实现维护。而查找中位数时只需要在线段树中找到第n/2大的数所在的叶子节点,叶子节点所对应的区间(叶子节点的区间l=r)值即为中位数。
AC代码:
#include<iostream>#include<stack>#include<algorithm>#include<cstdio>#include<cstring>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn=100002;int sum[maxn<<2];void pushUp(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){ if(l==r) { sum[rt]=0; return ; } int m=(l+r)>>1; //printf("l = %d r = %d root = %d\n",l,r,rt); build(lson); build(rson); pushUp(rt);}void update(int l,int r,int rt,int p,int v){ if(l==r) { if(v==0) sum[rt]--; else sum[rt]++; return ; } int m=(l+r)>>1; if(p<=m) update(lson,p,v); else update(rson,p,v); pushUp(rt);}int query(int l,int r,int rt,int num){ if(l==r) return l; int m=(l+r)>>1; if(sum[rt<<1]>=num) return query(lson,num); return query(rson,num-sum[rt<<1]);}void debug(){ printf("debug\n");}int main(){ //debug(); //freopen("in.txt","r",stdin); int t; build(1,maxn,1); //debug(); scanf("%d",&t); //cout<<t<<endl; stack<int>st; while(t--) { char buf[20]; scanf("%s",buf); if(buf[1]=='o') { if(st.size()) { printf("%d\n",st.top()); update(1,maxn,1,st.top(),0); st.pop(); } else puts("Invalid"); } else if(buf[1]=='u') { int x; scanf("%d",&x); st.push(x); update(1,maxn,1,x,1); } else { int cnt=st.size(); if(!cnt) { puts("Invalid"); continue; } if(cnt&1) cnt++; printf("%d\n",query(1,maxn,1,cnt>>1)); } } return 0;}
0 0
- L3-2. 堆栈(线段树单点更新)
- 团体程序设计天梯赛-练习集 L3-002. 堆栈 线段树 单点更新 解题报告
- L3-2. 堆栈(线段树)
- L3-002. 堆栈(线段树)
- 线段树+L3-002. 堆栈
- 线段树 单点更新
- 线段树单点更新
- 线段树 单点更新
- 单点更新线段树
- 线段树单点更新
- 线段树单点更新
- 线段树 单点更新
- 线段树 单点更新
- 线段树单点更新
- 线段树 单点更新
- 单点更新线段树
- 线段树单点更新
- 线段树,单点更新
- effective objective-c 2.0 笔记 第三章 :接口与API设计
- 关于Struts2+spring+maven中使用百度UEditor编辑器显示未找到上传数据的解决方案
- 分区分配方案
- Azure ServiceBus 学习记录
- PHP 基础教程1
- L3-2. 堆栈(线段树单点更新)
- 系统属性调用评估表
- APP上架流程
- 编译caffe
- 合作总结
- anagrams(medium)
- XMG CALayer隐式动画
- java实例化对象
- 卡特兰数