zoukankan      html  css  js  c++  java
  • 「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
    ",kth(t1)+add);
            }
        }
        matain();
        printf("%d
    ",leavetot);
        return 0;
    }
  • 相关阅读:
    ubuntu常用快捷键,不断更新中~
    C语言模拟漏斗
    浅谈webCam
    1001. A+B Format
    点、边、面——欧拉公式
    果园里的树
    生产计划
    Stanford Machine Learning 学习 2016/7/4
    paper reading
    paper reading in this week
  • 原文地址:https://www.cnblogs.com/mycups/p/8545152.html
Copyright © 2011-2022 走看看