hdu4441 splay

来源:互联网 发布:华为薪资 知乎 编辑:程序博客网 时间:2024/09/21 09:04

题意:给定一个序列 然后要求维护一个序列 使得这个序列是一个合法的队列结构 然后询问操作是对于+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 222222int 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;}

0 0
原创粉丝点击