• [bzoj1503][NOI2004]郁闷的出纳员


    题目很劲爆--OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

    大概就是要支持查询k大,区间改和删点。   $nleqslant 10^{5}$

    题解:就是一道很裸的平衡树呗。然后我突然决定用这道题学学treap,然后就莫名调了好久..

    #include<iostream>
    #include<cstdio>
    #define MN 100000
    #define INF 0x7FFFFFFF
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    inline int Ran()
    {
        static int x=23333;
        x^=(x<<13);x^=(x>>17);x^=(x<<5);return x;
    }
    
    char op[5];
    int fa[MN+5],c[MN+5][2],size[MN+5],val[MN+5],nn[MN+5],n,K,s[MN+5],cnt=0,rt=0,ans=0;
    
    inline void update(int x){size[x]=size[c[x][0]]+size[c[x][1]]+1;}
    
    void pushdown(int x)
    {
        int l=c[x][0],r=c[x][1];
        val[l]+=val[x];val[r]+=val[x];
        nn[l]+=val[x];nn[r]+=val[x];
        val[x]=0;
    }
    
    void rotate(int x)
    {
        int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
        c[z][c[z][1]==y]=x; if(y==rt)rt=x;
        fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
        c[y][l]=c[x][r];c[x][r]=y;
        update(y);update(x);
    }
    
    void ins(int x,int rk)
    {
        // if(++tms>MN*100)exit(0);
        if(!x)rt=++cnt; else
        {
            int t=(rk>nn[x]);pushdown(x);++size[x];
            while(c[x][t]) {x=c[x][t];++size[x];pushdown(x);t=rk>nn[x];}
            c[x][t]=++cnt;fa[cnt]=x;
        }
        size[cnt]=1;s[cnt]=Ran();nn[cnt]=rk;
        while(fa[cnt]&&s[cnt]>s[fa[cnt]])rotate(cnt);
    }
    
    int find(int x,int rk)
    {
        if(!x)return -1;
        if(val[x]) pushdown(x);
        int l=size[c[x][0]];
        if(l+1==rk)return x;
        if(l+1<rk) return find(c[x][1],rk-l-1);
        return find(c[x][0],rk);
    }
    
    void del(int x)
    {
        c[fa[x]][0]=c[x][1];fa[c[x][1]]=fa[x];if(x==rt) rt=c[x][1];
        while(x=fa[x])update(x);
    }
    
    int main()
    {
        n=read();K=read();s[0]=-INF;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",op);int x=read();
            if(op[0]=='I') {if(x>=K)ins(rt,x);}
            if(op[0]=='S') {nn[rt]-=x;val[rt]-=x;while((x=find(rt,1))>0&&nn[x]<K) del(x),++ans;}
            if(op[0]=='F') {printf("%d
    ",(x=find(rt,size[rt]-x+1))==-1?-1:nn[x]);}
            if(op[0]=='A') {nn[rt]+=x;val[rt]+=x;}
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    DJANGO
    前端--BootStrap
    前端--JQuery
    前端--JavaScript
    前端--CSS
    前端--HTML
    python中面试题积累
    python中一些小的知识点
    python中字典的增删改查及相关知识点
    python中列表的增删改查以及其它相关方法
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj1503.html
Copyright © 2020-2023  润新知