码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-03-11 19:21:22      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:amp   mat   har   gpo   c++   class   sid   its   return   

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;
}

 

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

标签:amp   mat   har   gpo   c++   class   sid   its   return   

原文地址:https://www.cnblogs.com/mycups/p/8545152.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!