[HDOJ 4967] Handling the Past [线段树]

来源:互联网 发布:南宁广电网络营业厅 编辑:程序博客网 时间:2024/04/28 22:29

作为一个服务器,你会收到一些关于一个栈的一些操作,他们分别是push,pop,top。由于网络原因,你收到操作的时间和操作实际发送的时间可能时不同的,甚至会是乱序的。

现在每个操作后边都会带着一个时间戳,所有的时间戳均不相同,代表这个操作时何时发送的。要求你对于收到的每一个top操作,立刻返回那个时刻的栈顶元素应该是什么。

观察可以发现,假设把目前收到的所有的操作都按照时间排序,那么对于时间t,返回的栈顶元素就是满足[l,t]区间内push操作恰好比pop操作的个数多1的最靠右的l。

所以我们用一棵线段树,对于push操作,在对应的时间位置上记录+1,pop操作记录-1。那么这棵线段树应该支持的操作有,点修改,查询满足[l,rr]的和等于x的最大的x。

又因为时间戳的范围时int的,所以我们要先进行离散化...

#include <cstdio>#include <map>#include <algorithm>#include <utility>#include <iostream>using namespace std;inline int in() {char c=getchar();while (c<'0'||c>'9') c=getchar();int ans=0;while (c>='0'&&c<='9') {ans=ans*10+c-'0';c=getchar();}return ans;}struct Query {int kind,value,time;void read() {char s[9];scanf("%s",s);if (s[1]=='u') {kind=1;value=in();time=in();} else if (s[1]=='o') {kind=2;time=in();} else {kind=3;time=in();}}};struct SeqNode {SeqNode *ls,*rs;int sum,rsum;void repair() {sum=ls->sum+rs->sum;rsum=max(ls->rsum+rs->sum,rs->rsum);}};SeqNode b[100000],*bp,*root;Query a[50000];map<int,int>c;map<int,int>d;int e[50001];int n;SeqNode *maketree(int l,int r) {SeqNode *ans=bp++;if (l==r) {ans->ls=ans->rs=NULL;ans->sum=ans->rsum=0;} else {int t=(l+r)/2;ans->ls=maketree(l,t);ans->rs=maketree(t+1,r);ans->repair();}return ans;}void set(SeqNode *from,int l,int r,int i,int x) {if (l==r) {from->sum=from->rsum=x;} else {int t=(l+r)/2;if (i<=t) set(from->ls,l,t,i,x);else set(from->rs,t+1,r,i,x);from->repair();}}pair<int,int> get(SeqNode *from,int l,int r,int rr,int sum) {//printf("%d %d %d %d\n",l,r,rr,sum);if (l==r) {if (from->sum==sum) return make_pair(l,0);else return make_pair(-1,from->sum);}int t=(l+r)/2;if (rr<=t) return get(from->ls,l,t,rr,sum);if (rr==r) {if (from->rsum<sum) return make_pair(-1,from->sum);if (from->rs->rsum>=sum) return get(from->rs,t+1,r,r,sum);else return get(from->ls,l,t,t,sum-from->rs->sum);} else {pair<int,int> tmp=get(from->rs,t+1,r,rr,sum);if (tmp.first!=-1) return tmp;if (from->ls->rsum<sum-tmp.second) return make_pair(-1,tmp.second+from->ls->sum);else return get(from->ls,l,t,t,sum-tmp.second);}}void print(SeqNode *from,int l,int r) {if (l!=r) {int t=(l+r)/2;print(from->ls,l,t);print(from->rs,t+1,r);} else {printf("%d ",from->sum);}}void print() {print(root,1,n);printf("\n");}int main() {int i,cas=1;while (scanf("%d",&n),n) {c.clear();d.clear();for (i=0;i<n;i++) {a[i].read();c[a[i].time]=1;d[a[i].time]=i;}i=1;for (map<int,int>::iterator it=c.begin();it!=c.end();it++,i++) {it->second=i;e[i]=it->first;}bp=b;root=maketree(1,n);printf("Case #%d:\n",cas++);//cerr<<cas<<' '<<n<<endl;//print();for (i=0;i<n;i++) {if (a[i].kind==1) {set(root,1,n,c[a[i].time],1);} else if (a[i].kind==2) {set(root,1,n,c[a[i].time],-1);} else {int tmp=get(root,1,n,c[a[i].time],1).first;if (tmp==-1) printf("-1\n");else {printf("%d\n",a[d[e[tmp]]].value);}}//print();//if (i%100==0) cerr<<cas<<' '<<i<<endl;}}return 0;}


0 0
原创粉丝点击