zoukankan      html  css  js  c++  java
  • 【Luogu】P1486郁闷的出纳员(Splay)

      题目链接

      名副其实的调了一下午……

      每做一道题都是对我那不规范的Splay代码的刀刻斧凿一般的修正啊……

      Splay。如果有一批员工不干了,那就找还能干的薪水最少的员工,把它splay到根,删除它的左子树。

      然后其他地方加一下标记乱搞就行,这个标记……跟NOIP蚯蚓那个题很像。qwq。

      

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<cstdlib>
    #define maxn 1000200
    using namespace std;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    int CNT;
    long long ans;
    struct Splay{
        struct Node{
            int    sum,size,fa,e[2],val;
        }tree[maxn];
        int point,tot,root;
        Splay(){point=tot=root=0;    }
        inline int iden(int x){    return x==tree[tree[x].fa].e[0]?0:1;    }
        inline void connect(int x,int fa,int how){    tree[x].fa=fa;    tree[fa].e[how]=x;    }
        inline void update(int x){    tree[x].size=tree[tree[x].e[0]].size+tree[tree[x].e[1]].size+tree[x].sum;    }
        inline void rotate(int x){
            int y=tree[x].fa;    int r=tree[y].fa;
            if(root==y)    root=x;
            int sony=iden(x);    int sonr=iden(y);
            int b=tree[x].e[sony^1];
            connect(b,y,sony);
            connect(y,x,sony^1);
            connect(x,r,sonr);
            update(y);    update(x);
        }
        void splay(int pos,int to){
            to=tree[to].fa;
            while(tree[pos].fa!=to){
                if(tree[tree[pos].fa].fa==to)    rotate(pos);
                else
                    if(iden(pos)==iden(tree[pos].fa)){
                        rotate(tree[pos].fa);
                        rotate(pos);
                    }
                    else{    rotate(pos);    rotate(pos);    }
            }
        }
        int create(int val,int fa){
            tree[++tot].val=val;    tree[tot].fa=fa;
            tree[tot].sum=tree[tot].size=1;
            return tot;
        }
        int build(int val){
            if(root==0){    root=create(val,0);    return root;    }
            int now=root;
            while(now){
                tree[now].size++;
                if(tree[now].val==val){    tree[now].sum++;    return now;    }
                int nxt=val<tree[now].val?0:1;
                if(tree[now].e[nxt]==0){
                    connect(create(val,now),now,nxt);
                    update(now);
                    return tot;
                }
                now=tree[now].e[nxt];
            }
            return 0;
        }
        inline void insert(int val){
            int p=build(val);
            if(++CNT==50){
                CNT=0;
                splay(p,root);
            }
        }
        inline int find(int val){
            int now=root;
            while(now){
                if(tree[now].val==val)    return now;
                int nxt=val<tree[now].val?0:1;
                now=tree[now].e[nxt];
            }
            return 0;
        }
        int upper(int val){
            int now=root,ans=root;
            while(now){
                if(tree[now].val==val)    return now;
                if(val<tree[now].val){
                    ans=now;
                    now=tree[now].e[0];
                }
                else    now=tree[now].e[1];
            }
            return ans;
        }
        void dele(int val){
            int deal=upper(val);
            if(tree[deal].val<val){
                ans+=tree[root].size;
                root=0;
                return;
            }
            splay(deal,root);
            ans+=tree[tree[deal].e[0]].size;
            tree[tree[deal].e[0]].fa=0;
            tree[deal].e[0]=0;
            update(deal);
        }
        int arank(int rnk){
            int now=root;
            while(rnk){
                int used=tree[now].size-tree[tree[now].e[1]].size;
                if(tree[tree[now].e[0]].size<rnk&&used>=rnk)    return tree[now].val;
                if(rnk<=used)    now=tree[now].e[0];
                else{
                    rnk-=used;
                    now=tree[now].e[1];
                }
            }
            if(++CNT==50&&now){
                splay(now,root);
                CNT=0;
            }
            return tree[now].val;
        }
        int query(int rnk,long long tag){
            if(tree[root].size<rnk)    return -1;
            return arank(tree[root].size-rnk+1)+tag;
        }
    }s;
    long long tag=0;
    int main(){int n=read(),m=read();
        for(int i=1;i<=n;++i){
            char c[10];int x;
            scanf("%s%d",c,&x);
            switch(c[0]){
                case 'I':
                    if(x>=m)    s.insert(x-tag);    break;
                case 'A':    tag+=x;    break;
                case 'S':
                    tag-=x;    s.dele(m-tag);    break;
                case 'F':    printf("%d
    ",s.query(x,tag));    break;
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    ubuntu下安装JDK(复制)
    idea的ssm搭建(复制)
    linux常用命令(复制)
    Ubuntu安装nginx(复制)
    win7分盘(复制)
    mysql环境变量配置(复制)
    mysql的下载及配置(复制1)
    java环境变量的配置
    Windows 右键添加「cmd 打开」
    快速开启Windows 的各种任务及 bat(ch)脚本
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8305147.html
Copyright © 2011-2022 走看看