【HYSBZ 1503: [NOI2004]】郁闷的出纳员——伸展树
来源:互联网 发布:集成电路版图设计 知乎 编辑:程序博客网 时间:2024/05/21 16:59
Time Limit: 5 Sec Memory Limit: 64 MB
Description
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?
Input
Output
输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。
Sample Input
9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
Sample Output
10
20
-1
2
HINT
I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000
题意就不说了,看看明白了,这是第一次用数组写伸展树,感觉爽呆了,突然发现大神们将代码提炼的好短。
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <string>#include <vector>#include <limits>#include <algorithm>using namespace std;typedef long long LL;const int Max = 100010;const int INF = 0x3f3f3f3f;struct SplayTree{ int num[Max],pre[Max],next[Max][2],key[Max]; int root,Size; void PushUp(int x) //向上更新,计算以自己为根节点的树中节点的个数 { num[x] = num[next[x][0]] + num[next[x][1]]+1; } void Rotate(int x,int kind)//伸展操作 { int y = pre[x]; int z = pre[y]; next[y][!kind] = next[x][kind]; pre[next[x][kind]] = y; next[z][next[z][1]==y] = x; pre[x] = z; next[x][kind] = y; pre[y] = x; PushUp(y); PushUp(x); } void Splay(int x,int goal) { if(x!=goal) { while(pre[x]!=goal) { if(next[pre[x]][0] == x) { Rotate(x,1); } else Rotate(x,0); } } if(!goal) root = x; } void NewNode(int &x,int y,int val) { x = ++Size; num[x] = 1; pre[x] = y; next[x][0] = next[x][1] = 0; key[x] = val; next[y][val>key[y]] = x; } void Insert(int val)//插入节点 { int x,y; for(x = root,y = 0;x;x = next[x][val>key[x]]) { y = x; num[x]++; } NewNode(x,y,val); Splay(x,0); } int Search(int val) //查询比小于等于val的节点的位置 { int res,x; for(res = 0, x = root;x;x = next[x][val>key[x]]) { if(key[x] >= val && key[res] >= key[x]) { res = x; } } return res; } int Select(int k)//查找第k大。 { int x = root; k = num[root]-k; for(x = root; num[next[x][0]]+1!=k;) { if(num[next[x][0]]+1<k) { k -= num[next[x][0]]+1; x = next[x][1]; } else x = next[x][0]; } Splay(x,0); return key[x]; } void Init() { root = Size = 0; num[0] = next[0][0] = next[0][1] = pre[0] ; key[0] = INF; Insert(INF); }}Tr;int main(){ int q,Mi,diff,ans,data; char op[2]; while(~scanf("%d %d",&q,&Mi)) { Tr.Init(); diff = ans = 0; while(q--) { scanf("%s %d",op,&data); if(op[0] == 'I') { if(data >= Mi) { Tr.Insert(data-Mi+diff); } } else if(op[0] == 'A') { diff-=data; } else if(op[0] == 'S') { diff += data; Tr.Splay(Tr.Search(diff),0); ans+=Tr.num[Tr.next[Tr.root][0]]; Tr.num[Tr.root] -= Tr.num[Tr.next[Tr.root][0]]; Tr.next[Tr.root][0] = 0; } else { if(data>=Tr.num[Tr.root]) { printf("-1\n"); } else { printf("%d\n",Tr.Select(data)+Mi-diff); } } } printf("%d\n",ans); } return 0;}
- 【HYSBZ 1503: [NOI2004]】郁闷的出纳员——伸展树
- bzoj 1503: [NOI2004]郁闷的出纳员 (伸展树)
- bzoj1503: [NOI2004]郁闷的出纳员(伸展树)
- 1503: [NOI2004]郁闷的出纳员
- noi2004 郁闷的出纳员
- [NOI2004]郁闷的出纳员
- NOI2004 郁闷的出纳员
- NOI2004 郁闷的出纳员
- NOI2004 郁闷的出纳员
- NOI2004 - 郁闷的出纳员
- NOI2004 郁闷的出纳员
- NOI2004郁闷的出纳员
- 【NOI2004】郁闷的出纳员
- [NOI2004]郁闷的出纳员
- [NOI2004]郁闷的出纳员
- [NOI2004]郁闷的出纳员
- NOI2004 郁闷的出纳员
- NOI2004 郁闷的出纳员
- NYOJ 题目716 River Crossing
- android apk安装到模拟器 不显示
- [弦图 最小染色 完美消除序列 MCS算法] BZOJ 1006 [HNOI2008]神奇的国度
- c的调试
- OC 对象整合练习题
- 【HYSBZ 1503: [NOI2004]】郁闷的出纳员——伸展树
- 1003 Problem C
- Maven的作用
- 媒体和资源
- win2003 iis .net4.0 迁移至win2008 iis 7.5的问题
- 0049 分布式中ssh本地登陆和两台电脑相互登陆配置方法
- 【算法分析】回溯法解八皇后问题(n皇后问题)
- 逆向分析 Android 程序
- [弦图判定 完美消除序列 MCS算法] BZOJ 1242 Zju1015 Fishing Net弦图判定