题意:给定一个序列 然后要求维护一个序列 使得这个序列是一个合法的队列结构 然后询问操作是对于+i -i之间的和是多少 删除操作 在原定序列中删除+i 和-i 插入操作插入+i的位置 然后-i的位置是最右边的合法位置
解法:直接上splay就可以了 不过调整了比较久的时间 实际上这三个操作都不是很难
#include<set>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
#define ls ch[rt][0]
#define rs ch[rt][1]
#define rrs ch[root][1]
#define rls ch[root][0]
#define maxn 222222
int ch[maxn][2],fa[maxn],num[maxn],pos[maxn],neg[maxn],val[maxn];
ll sum[maxn];
int root,clc;
void up(int rt){
sum[rt]=val[rt];num[rt]=1;
pos[rt]=(val[rt]>0);
neg[rt]=(val[rt]<=0);
for(int i=0;i<2;++i){
int son=ch[rt][i];
if(!son)continue;
sum[rt]+=sum[son],num[rt]+=num[son],pos[rt]+=pos[son],neg[rt]+=neg[son];
}
}
inline void rot(int rt){
int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side];
fa[ll]=f,ch[f][side]=ll;
fa[rt]=fa[f],ch[fa[f]][ch[fa[f]][1]==f]=rt;
fa[f]=rt,ch[rt][!side]=f;
up(f),up(rt);
}
inline void splay(int rt,int aim){
while(fa[rt]!=aim){
int f=fa[rt],ff=fa[f];
if(ff==aim)rot(rt);
if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt);
else rot(rt),rot(rt);
}if(!aim)root=rt;
}
inline void find(int tot,int sub){
int rt=sub;
while(1){
if(tot==num[ls]+1)break;
if(num[ls]>=tot)rt=ls;
else tot-=num[ls]+1,rt=rs;
}
splay(rt,fa[sub]);
}
inline int count(int posi){
int res=0,rt=root;
while(rt!=0){
int cnt=(ls==0?(val[rt]<=0):(val[rt]<=0)+neg[ls]);
if(posi<cnt)rt=ls;
else posi-=cnt,res+=(ls==0?1:1+num[ls]),rt=rs;
}return res;
}
set<int>se;
int l[maxn],r[maxn],m,k,_=0;
char op[111];
inline void init(){
ch[2][0]=ch[2][1]=ch[1][1]=0;ch[1][0]=2;
fa[2]=1;fa[1]=0;val[1]=val[2]=0;up(2),up(1);
val[0]=num[0]=0;
root=1,clc=2;
}
int main(){
while(~scanf("%d",&m)){
printf("Case #%d:\n",++_);
se.clear();
for(int i=1;i<=100000;++i){se.insert(i);l[i]=r[i]=-1;}
init();
while(m--){
scanf("%s %d",op,&k);
if(*op=='i'){
int w=(*(se.begin()));se.erase(w);
find(k+1,root);
find(1,rrs);
ch[rrs][0]=++clc;
val[clc]=w;ch[clc][0]=ch[clc][1]=0,fa[clc]=rrs;
up(clc);splay(clc,0);
l[w]=clc;
int cnt=count(pos[ch[clc][0]]+1);
find(cnt,root);
find(1,rrs);
ch[rrs][0]=++clc;
val[clc]=-w;
ch[clc][0]=ch[clc][1]=0;
fa[clc]=rrs;up(clc);
splay(clc,0);
r[w]=clc;
}
else if(*op=='q'){
splay(l[k],0);
splay(r[k],root);
ll ans=(ch[r[k]][0]==0?0:sum[ch[r[k]][0]]);
printf("%I64d\n",ans);
}
else if(*op=='r'){
splay(l[k],0);
int cnt=num[rls];
find(cnt,root),find(2,rrs);ch[rrs][0]=0;
up(rrs),up(root);
splay(r[k],0);
cnt=num[rls];
find(cnt,root),find(2,rrs);ch[rrs][0]=0;
up(rrs),up(root);
se.insert(k);
l[k]=r[k]=-1;
}
}
}
return 0;
}