「luogu1486」 [NOI2004]郁闷的出纳员

Splay:

#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int n,minv,root,add;
int fa[N],ch[N][2],siz[N],v[N],cnt[N],totnode,leavetot;
void updata(int k){
    if(!k) return;
    siz[k]=cnt[k];
    if(ch[k][0]) siz[k]+=siz[ch[k][0]];
    if(ch[k][1]) siz[k]+=siz[ch[k][1]];
    return;
}
inline bool getside(int k){return ch[fa[k]][1]==k;}
void rotate(int k){
    int old=fa[k],oldf=fa[old],sidek=getside(k),sideold=getside(old);
    ch[old][sidek]=ch[k][sidek^1];
    if(ch[k][sidek^1]) fa[ch[k][sidek^1]]=old;
    ch[k][sidek^1]=old,fa[old]=k,fa[k]=oldf;
    if(oldf) ch[oldf][sideold]=k;
    updata(old);updata(k);
    if(!fa[k]) root=k;
    return;
}
void splay(int k,int aim){
    for(int i=fa[k];i!=aim;i=fa[k])
        rotate(getside(k)==getside(i)&&fa[i]!=aim?i:k);
    return;
}
void insert(int x){
    if(!root){
        root=++totnode;
        v[root]=x,siz[root]=cnt[root]=1;
        return;
    }
    int now=root;
    while(1){
        if(v[now]==x){
            cnt[now]++;
            updata(fa[now]);
            splay(now,0);
            return;
        }else if(v[now]>x){
            if(!ch[now][0]){
                ch[now][0]=++totnode;
                fa[totnode]=now,v[totnode]=x,cnt[totnode]=1;
                updata(now);
                splay(totnode,0);
                return;
            }
            now=ch[now][0];
        }else{
            if(!ch[now][1]){
                ch[now][1]=++totnode;
                fa[totnode]=now,v[totnode]=x,cnt[totnode]=1;
                updata(now);
                splay(totnode,0);
                return;
            }
            now=ch[now][1];
        }
    }
}
void matain(){
    int now=root;
    while(1){
        if(v[now]+add==minv){
            break;
        }else if(v[now]+add<minv){
            if(!ch[now][1]) break;
            now=ch[now][1];
        }else{
            if(!ch[now][0]) break;
            now=ch[now][0];
        }
    }
    splay(now,0);
    if(v[root]+add<minv){
        leavetot+=siz[ch[root][0]]+cnt[root],root=ch[root][1],fa[root]=0;
        updata(root);
    }else{
        leavetot+=siz[ch[root][0]],ch[root][0]=0;
        updata(root);
    }
    return;
}
int kth(int k){
    int now=root;
    while(1){
        if(siz[ch[now][1]]>=k){
            now=ch[now][1];
        }else if(siz[ch[now][1]]+cnt[now]<k){
            if(!ch[now][0]){
                splay(now,0);
                return -add-1;
            }
            k-=siz[ch[now][1]]+cnt[now],now=ch[now][0];
        }else break;
    }
    splay(now,0);
    return v[root];
}
int main(){
    char opt[10];
    int t1;
    scanf("%d%d",&n,&minv);
    while(n--){
        scanf("%s%d",opt,&t1);
        if(opt[0]=='I'){
            if(t1<minv) continue;
            insert(t1-add);
        }else if(opt[0]=='A'){
            add+=t1;
            matain();
        }else if(opt[0]=='S'){
            add-=t1;
            matain();
        }else{
            printf("%d\n",kth(t1)+add);
        }
    }
    matain();
    printf("%d\n",leavetot);
    return 0;
}

 

posted @ 2018-03-11 18:00  Cupcake  阅读(96)  评论(0编辑  收藏  举报