P1486 [NOI2004]郁闷的出纳员(Treap树)

OIER 公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把当前在公司的所有员工的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。

工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。

老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第 kk 多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。

好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

如果某个员工的初始工资低于最低工资标准,那么将不计入最后的答案内。

题解:

就是一些Treap树的基本操作,过的比较轻松,对Treap树的掌握渐渐熟练起来了。

数据范围改一下就是一道树状数组套二分的题,哈哈哈

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+100;
const int inf=1e9;
int n;
int Min;
int ans;

struct Treap_tree {
    int ch[2];
    int v;
    int dat;//优先级 
    int size;//子树节点数 
    int cnt;//重复数 
}t[maxn];
int tot;
int root;
int newNode (int v) {
    tot++;
    t[tot].v=v;
    t[tot].dat=rand();//随机优先级
    t[tot].size=1;
    t[tot].cnt=1;
    return tot; 
} 
void pushup (int x) {
    t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
}
void build () {
    root=newNode(-inf);
    t[root].ch[1]=newNode(inf);
    pushup(root);
}
void rotate (int &id,int d) {
    int tt=t[id].ch[d^1];
    t[id].ch[d^1]=t[tt].ch[d];
    t[tt].ch[d]=id;
    id=tt;
    pushup(t[id].ch[d]);
    pushup(id);
}
void ins (int &id,int v) {
    if (!id) {
        id=newNode(v);
        return;
    }
    if (v==t[id].v) t[id].cnt++;
    else {
        ins(t[id].ch[v>t[id].v],v);
        if (t[id].dat<t[t[id].ch[v>t[id].v]].dat) rotate(id,v<t[id].v);
    }
    pushup(id);
}
void remove (int &id,int v) {
    if (!id) return;
    if (v==t[id].v) {
        
        if (t[id].ch[0]||t[id].ch[1]) {
            if (!t[id].ch[1]||t[t[id].ch[0]].dat>t[t[id].ch[1]].dat) {
                rotate(id,1);
                remove(t[id].ch[1],v);
            }
            else {
                rotate(id,0);
                remove(t[id].ch[0],v);
            }
            pushup(id);
        }
        else
            id=0;
        return;
    }
    remove(t[id].ch[v>t[id].v],v);
    pushup(id);
}
int kth (int id,int k) {
    if (!id) return inf;
    if (k<=t[t[id].ch[0]].size)
        return kth(t[id].ch[0],k);
    else if (k<=t[t[id].ch[0]].size+t[id].cnt)
        return t[id].v;
    else
        return kth(t[id].ch[1],k-t[t[id].ch[0]].size-t[id].cnt);
}
void bfs (int id,int k) {
    queue<int> q;
    q.push(id);
    vector<int> wjm;
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        t[u].v+=k;
        if (t[u].v<Min) wjm.push_back(u);
        if (t[u].ch[0])
            q.push(t[u].ch[0]);
        if (t[u].ch[1])
            q.push(t[u].ch[1]);
    }
    for (int i=0;i<wjm.size();i++)
        ans+=t[wjm[i]].cnt,remove(root,t[wjm[i]].v);
}


int main () {
    scanf("%d%d",&n,&Min);
    ans=0;
    for (int i=1;i<=n;i++) {
        string s;
        int k;
        cin>>s>>k;
        if (s=="I"&&k>=Min)
            ins(root,k);
        if (s=="A")
            bfs(root,k);
        if (s=="S")
            bfs(root,-k);
        if (s=="F") {
            int sum=t[root].size;
            if (k>sum) {
                printf("-1
");
                continue;
            }
            printf("%d
",kth(root,sum-k+1));
        }
    }
    printf("%d
",ans);
}
原文地址:https://www.cnblogs.com/zhanglichen/p/13429552.html