【NOI2004】郁闷的出纳员(splay)
来源:互联网 发布:书法集字软件 编辑:程序博客网 时间:2024/05/22 12:32
题面
Description
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工 作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把 他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。
工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离 开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员 工,我就得为他新建一个工资档案。
老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。
好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?
Input
第一行有两个非负整数n和min。n表示下面有多少条命令,min表示工资下界。接下来的n行,每行表示一条命令。
命令可以是以下四种之一:
名称 格式 作用
I命令 I k 新建一个工资档案,初始工资为k。如果某员工的初始工资低于工资下界,他将立刻离开公司。
A命令 A k 把每位员工的工资加上k
S命令 S k 把每位员工的工资扣除k
F命令 F k 查询第k多的工资
I命令、A命令、S命令中的k是一个非负整数,F命令中的k是一个正整数。 在初始时,可以认为公司里一个员工也没有。
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
题解
插入和查询操作都是splay最基础的操作,不解释了。。
注意一下插入,存一下当前工资的总的增加情况,插入的时候减一下
问题在于如何处理删除
那么,找到当前减去之后的能够满足条件的最少区间的后缀
将后缀旋转到根节点
很显然,当前根节点的左儿子就是要删去的节点
统计一下即可
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<algorithm>using namespace std;#define INF 1000000000#define MAX 110000int root;inline int read(){ register int x=0,t=1; register char ch=getchar(); while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-'){t=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();} return x*t;}struct Node{ int ch[2]; int val; int ff; int cnt; int size;}t[MAX];int tot,n,mm,ans,add;inline void pushup(int x){ t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;}inline void rotate(int x){ int y=t[x].ff; int z=t[y].ff; int k=(x==t[y].ch[1]); t[z].ch[y==t[z].ch[1]]=x; t[x].ff=z; t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y; t[x].ch[k^1]=y; t[y].ff=x; pushup(y);pushup(x);}inline void splay(int x,int goal){ while(t[x].ff!=goal) { int y=t[x].ff; int z=t[y].ff; if(z!=goal) (t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y); rotate(x); } if(goal==0)root=x;}inline void insert(int x){ int u=root,ff=0; while(u&&t[u].val!=x) { ff=u; u=t[u].ch[x>t[u].val]; } if(u)t[u].cnt++; else { u=++tot; if(ff)t[ff].ch[x>t[ff].val]=u; t[u].ch[0]=t[u].ch[1]=0; t[u].val=x; t[u].cnt=1; t[u].size=1; t[u].ff=ff; } splay(u,0);}inline void find(int x){ int u=root; if(!u)return; while(t[u].ch[x>t[u].val]&&t[u].val!=x) u=t[u].ch[x>t[u].val]; splay(u,0);}inline int Next(int x,int f){ find(x); int u=root; if(t[u].val>=x&&f)return u; if(t[u].val<=x&&!f)return u; u=t[u].ch[f]; while(t[u].ch[f^1])u=t[u].ch[f^1]; return u;}inline int kth(int x){ int u=root; if(t[u].size<x||x<=0)return -INF; while(233) { int y=t[u].ch[0]; if(t[y].size+t[u].cnt<x) { x-=t[y].size+t[u].cnt; u=t[u].ch[1]; } else if(t[y].size>=x) u=y; else return t[u].val; }}int main(){ insert(+INF); scanf("%d%d",&n,&mm); int peo=0; while(n--) { int x;char ch[3]; scanf("%s%d",ch,&x); if(ch[0]=='I') { if(x<mm); else { insert(x-add); peo++; } } if(ch[0]=='A') add+=x; if(ch[0]=='S') { add-=x; int gg=Next(mm-add,1); splay(gg,0); ans+=t[t[root].ch[0]].size; peo-=t[t[root].ch[0]].size; t[t[root].ch[0]].size=t[t[root].ch[0]].cnt=0; t[root].ch[0]=0;t[0].size=0; pushup(root); } if(ch[0]=='F') { int gg=kth(peo-x+1); printf("%d\n",gg==-INF?-1:(gg+add)); } } printf("%d\n",ans); return 0;}
- 【NOI2004】郁闷的出纳员(splay)
- bzoj1503 [NOI2004]郁闷的出纳员(splay)
- [NOI2004]郁闷的出纳员 (Splay)
- (题解)(Splay)NOI2004郁闷的出纳员
- 【NOI2004】郁闷的出纳员(splay tree WA中。。)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- BZOJ 1503 [NOI2004] :郁闷的出纳员(Splay)
- 【NOI2004】郁闷的出纳员 // SPLAY TREE
- bzoj 1503 [NOI2004]郁闷的出纳员 splay
- 【NOI2004】【splay】【SBT】郁闷的出纳员
- BZOJ 1503 [NOI2004]郁闷的出纳员 (splay)
- [BZOJ1503]NOI2004 郁闷的出纳员|splay
- 【bzoj1503】[NOI2004]郁闷的出纳员 Splay
- 1503: [NOI2004]郁闷的出纳员【splay】
- 【BZOJ1503】[NOI2004]郁闷的出纳员【Splay】
- 【NOI2004】郁闷的出纳员Splay版
- bzoj 1503: [NOI2004]郁闷的出纳员 splay
- Android Service的bindService和startService混合使用及其关闭分析
- JAVA学习57_ Java千百问_02基本使用(003)_不使用IDE如何打jar包
- python 经典100例 (61-80)
- jquery validate 的自定义验证开始时间不能大于结束时间
- parallel studio xe 2017 update4 编译器套件学生版下载及密钥的申请
- 【NOI2004】郁闷的出纳员(splay)
- 排序算法-交换排序之快速排序
- 简单的程序诠释C++ STL算法:copy
- 【物联网云端对接-4】通过MQTT协议与百度云进行云端通信
- Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询
- C语言union类型和C语言 uchar类型的个人见解
- 8.23训练总结
- C#操作数据库简单辅助工具
- JavaScript基础系列之五 浏览器