刷题集--郁闷的出纳员

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

一棵无旋treap就好了。

#include<bits/stdc++.h>
using namespace std;
const int N=200010;
struct gg{
    int ls,rs,w,rnd,laz,sz;
}node[N];int tot=0,mn,rt,bps=0,ans=0;
vector<int>bin;
void push_up(int x)
{node[x].sz=node[node[x].ls].sz+node[node[x].rs].sz+1;}
int new_node(int w)
{
    int nw;
    if(bps<bin.size())nw=bin[bps++];
    else nw=++tot;
    node[nw].rnd=rand()*rand(),node[nw].laz=0;
    node[nw].ls=node[nw].rs=0;
    node[nw].sz=1,node[nw].w=w;
    return nw;
}
void clear(int x)
{
    if(node[x].ls)clear(node[x].ls);
    ++ans;bin.push_back(x);
    if(node[x].rs)clear(node[x].rs);
}
void push_down(int x)
{
    if(node[x].laz)
    {
        if(node[x].ls)node[node[x].ls].w+=node[x].laz,node[node[x].ls].laz+=node[x].laz;
        if(node[x].rs)node[node[x].rs].w+=node[x].laz,node[node[x].rs].laz+=node[x].laz;
        node[x].laz=0;
    }
}
int mg(int x,int y)
{
    if(!x||!y)return x+y;
    push_down(x),push_down(y);
    if(node[x].rnd<=node[y].rnd)
    {
        node[x].rs=mg(node[x].rs,y);
        push_up(x);
        return x;
    }
    else
    {
        node[y].ls=mg(x,node[y].ls);
        push_up(y);
        return y;
    }
}
void split1(int nw,int k,int &x,int &y)
{
    if(!nw)x=y=0;
    else
    {
        push_down(nw);
        if(node[node[nw].ls].sz>=k)y=nw,split1(node[nw].ls,k,x,node[nw].ls);
        else x=nw,split1(node[nw].rs,k-node[node[nw].ls].sz-1,node[nw].rs,y);
        push_up(nw);
    }
}
void split2(int nw,int k,int &x,int &y)
{
    if(!nw)x=y=0;
    else
    {
        push_down(nw);
        if(node[nw].w<=k)x=nw,split2(node[nw].rs,k,node[nw].rs,y);
        else y=nw,split2(node[nw].ls,k,x,node[nw].ls);
        push_up(nw);
    }
}
void ins(int nw)
{
    int x,y;
    if(nw<mn)return;
    split2(rt,nw,x,y);
    rt=mg(mg(x,new_node(nw)),y);
    return;
}
void add(int nw)
{
    int x,y;
    node[rt].w+=nw,node[rt].laz+=nw;
    if(nw<0)
    {
        split2(rt,mn-1,x,y);
        if(x)clear(x);rt=y;
    }
    return;
}
void ask(int nw)
{
    int x,y,z;
    nw=node[rt].sz-nw+1;
    if(nw<=0){puts("-1");return;}
    split1(rt,nw-1,x,y);
    split1(y,1,y,z);
    if(y)printf("%d\n",node[y].w);
    else puts("-1");
    rt=mg(x,mg(y,z));
    return;
}
int main()
{
    srand(23336666);
    int n,nw;char s[10];
    scanf("%d%d",&n,&mn);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        scanf("%d",&nw);
        if(s[0]=='I')ins(nw);
        else if(s[0]=='A')add(nw);
        else if(s[0]=='S')add(-nw);
        else ask(nw);
    }
    printf("%d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/caoyang1123/article/details/82619775