• bzoj 1503 [NOI2004]郁闷的出纳员 splay


    http://www.lydsy.com/JudgeOnline/problem.php?id=1503

    用w值记录它的加减情况,加(减)操作加在w上加(减)val,当新来一个的时候你插入树中应该是以前工资未变化时的相对值,也就是val-w

    // File Name: ACM/bzoj/1503.cpp
    // Author: Zlbing
    // Created Time: 2013年08月08日 星期四 14时29分46秒
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=2e5+100;
    int lim;
    struct SplayTree {  
        int sz[MAXN];  
        int ch[MAXN][2];  
        int pre[MAXN];  
        int rt,top;  
        inline void up(int x){  
            sz[x]  = cnt[x]  + sz[ ch[x][0] ] + sz[ ch[x][1] ];  
        }  
        inline void Rotate(int x,int f){  
            int y=pre[x];  
            ch[y][!f] = ch[x][f];  
            pre[ ch[x][f] ] = y;  
            pre[x] = pre[y];  
            if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;  
            ch[x][f] = y;  
            pre[y] = x;  
            up(y);  
        }  
        inline void Splay(int x,int goal){//将x旋转到goal的下面  
            while(pre[x] != goal){  
                if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);  
                else   {  
                    int y=pre[x],z=pre[y];  
                    int f = (ch[z][0]==y);  
                    if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);  
                    else Rotate(y,f),Rotate(x,f);  
                }  
            }  
            up(x);  
            if(goal==0) rt=x;  
        }  
        inline void RTO(int k,int goal){//将第k位数旋转到goal的下面  
            int x=rt;  
            while(sz[ ch[x][0] ] != k-1) {  
                if(k < sz[ ch[x][0] ]+1) x=ch[x][0];  
                else {  
                    k-=(sz[ ch[x][0] ]+1);  
                    x = ch[x][1];  
                }  
            }  
            Splay(x,goal);  
        }  
        inline void vist(int x){  
            if(x){  
                printf("结点%2d : 左儿子  %2d   右儿子  %2d   %2d sz=%d
    ",x,ch[x][0],ch[x][1],val[x],sz[x]);  
                vist(ch[x][0]);  
                vist(ch[x][1]);  
            }  
        }  
        inline void Newnode(int &x,int c){  
            x=++top;  
            ch[x][0] = ch[x][1] = pre[x] = 0;  
            sz[x]=1; cnt[x]=1;  
            val[x] = c;  
        }  
        inline void init(){  
            sum=ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;  
            rt=top=0; cnt[0]=0;  
        }  
        inline void Insert(int &x,int key,int f){  
            if(!x) {  
                Newnode(x,key);  
                pre[x]=f;  
                Splay(x,0);  
                return ;  
            }  
            if(key==val[x]){  
                cnt[x]++;  
                sz[x]++;  
                Splay(x,0);  
                return ;  
            }else if(key<val[x]) {  
                Insert(ch[x][0],key,x);  
            } else {  
                Insert(ch[x][1],key,x);  
            }  
            up(x);  
        }  
        void del(int &x,int f){  
            if(!x) return ;  
            if(val[x]>=lim){  
                del(ch[x][0],x);  
            } else {  
                sum+=sz[ch[x][0]]+cnt[x];  
                x=ch[x][1];   
                pre[x]=f;  
                if(f==0) rt=x;  
                del(x,f);  
            }  
            if(x)  up(x);  
        }  
        inline void update(){  
            del(rt,0);  
        }  
        inline int find_kth(int x,int k){  
            if(k<sz[ch[x][0]]+1) {  
                return find_kth(ch[x][0],k);  
            }else if(k > sz[ ch[x][0] ] + cnt[x] )   
                return find_kth(ch[x][1],k-sz[ch[x][0]]-cnt[x]);  
            else{   
                Splay(x,0);  
                return val[x];  
            }  
        }  
        int cnt[MAXN];  
        int val[MAXN];  
        int sum;  
    }spt;  
    int main()
    {
        int n;
        int m;
        char op[5];
        scanf("%d%d",&n,&m);
        int w=0;
        spt.init();
        while(n--)
        {
            int k;
            scanf("%s%d",op,&k);
            if(op[0]=='I')
            {
                if(k<m){
                    continue;
                }
                spt.Insert(spt.rt,k-w,0);
            }
            else if(op[0]=='A')
            {
                w+=k;
            }
            else if(op[0]=='S')
            {
                w-=k;
                lim=m-w;
                spt.update();
            }
            else
            {
                int sz=spt.sz[spt.rt];
                if(k>sz)printf("-1
    ");
                else 
                {
                    printf("%d
    ",spt.find_kth(spt.rt,sz-k+1)+w);
                }
            }
        }
        printf("%d
    ",spt.sum);
        return 0;
    }
  • 相关阅读:
    pymysql模块的使用
    MySQL创建用户、授权和备份
    多表查询
    单表查询
    mysql性能优化2
    mysql性能优化1
    穷人的思维
    thinkphp所有参数配置
    似水流年
    memecached常用命令
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3248317.html
Copyright © 2020-2023  润新知