作为一个服务器,你会收到一些关于一个栈的一些操作,他们分别是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;
}