BZOJ1503:[NOI2004]郁闷的出纳员——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1503
(题面复制的洛谷的,因为洛谷好看)
题目描述
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。
工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。
老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。
好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?
如果某个员工的初始工资低于最低工资标准,那么将不计入最后的答案内
输入输出格式
输入格式:
第一行有两个非负整数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是一个正整数。
在初始时,可以认为公司里一个员工也没有。
输出格式:
输出文件的行数为F命令的条数加一。
对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。
输出文件的最后一行包含一个整数,为离开公司的员工的总数。
输入输出样例
9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
10
20
-1
2
说明
I命令的条数不超过100000
A命令和S命令的总条数不超过100
F命令的条数不超过100000
每次工资调整的调整量不超过1000
新员工的工资不超过100000
————————————————————————————
维护一棵平衡树,记录一个det记录这棵树上的点最后需要加上det才为真正的值。
于是我们每次插入的人的钱都是k-det。
当我们查询哪些人要被删的时候,我们插入minn-det,然后删掉该点的左子树即可。
那么询问第k大就暴力在平衡树搜即可(方法基本同线段树的搜索)
#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int fa[N],tr[N][],key[N],cnt[N],size[N];
int root,sz;
inline void clear(int x){
fa[x]=tr[x][]=tr[x][]=key[x]=cnt[x]=size[x]=;
return;
}
inline bool get(int x){
return tr[fa[x]][]==x;
}
inline void update(int x){
if(x){
size[x]=cnt[x];
if(tr[x][])size[x]+=size[tr[x][]];
if(tr[x][])size[x]+=size[tr[x][]];
}
return;
}
inline void rotate(int x){
int old=fa[x],oldf=fa[old],which=get(x);
tr[old][which]=tr[x][which^];fa[tr[old][which]]=old;
fa[old]=x;tr[x][which^]=old;fa[x]=oldf;
if(oldf)tr[oldf][tr[oldf][]==old]=x;
update(old);update(x);
return;
}
inline void splay(int x){
int f=fa[x];
while(f){
if(fa[f])rotate((get(x)==get(f)?f:x));
rotate(x);f=fa[x];
}
root=x;
return;
}
inline void insert(int v){
if(!root){
sz++;tr[sz][]=tr[sz][]=fa[sz]=;
key[sz]=v;cnt[sz]=size[sz]=;root=sz;
return;
}
int now=root,f=;
while(){
if(key[now]==v){
cnt[now]++;update(now);update(f);splay(now);
break;
}
f=now;
now=tr[now][key[now]<v];
if(!now){
sz++;tr[sz][]=tr[sz][]=;fa[sz]=f;
key[sz]=v;cnt[sz]=size[sz]=;
tr[f][key[f]<v]=sz;
update(f);splay(sz);
break;
}
}
return;
}
inline void del(){
if(cnt[root]>){
cnt[root]--;
size[root]--;
return;
}
if(!tr[root][]){
clear(root);root=;return;
}
int oldroot=root;root=tr[root][];fa[root]=;clear(oldroot);
return;
}
int query(int k,int x){
if(size[tr[x][]]<k&&k<=cnt[x]+size[tr[x][]])return key[x];
else if(size[tr[x][]]<k)return query(k-size[tr[x][]]-cnt[x],tr[x][]);
else return query(k,tr[x][]);
}
int main(){
int n=read();
int minn=read();
int det=;
int delnum=;
for(int i=;i<=n;i++){
char ch=;
while(ch<'A'||ch>'Z')ch=getchar();
int k=read();
if(ch=='I')if(k>=minn)insert(k-det);
if(ch=='A')det+=k;
if(ch=='S'){
det-=k;
insert(minn-det);
size[root]-=size[tr[root][]];
delnum+=size[tr[root][]];
clear(tr[root][]);
tr[root][]=;
del();
}
if(ch=='F'){
if(size[root]<k)puts("-1");
else{
printf("%d\n",query(k,root)+det);
}
}
}
printf("%d\n",delnum);
return ;
}
BZOJ1503:[NOI2004]郁闷的出纳员——题解的更多相关文章
- [BZOJ1503][NOI2004]郁闷的出纳员
[BZOJ1503][NOI2004]郁闷的出纳员 试题描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是 ...
- [BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MB Description OIER公司是一家大型专业化软件公司,有着数以万计的员 ...
- bzoj1503: [NOI2004]郁闷的出纳员(伸展树)
1503: [NOI2004]郁闷的出纳员 题目:传送门 题解: 修改操作一共不超过100 直接暴力在伸展树上修改 代码: #include<cstdio> #include<cst ...
- bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 8705 Solved: 3027[Submit][Statu ...
- 【题解】 bzoj1503: [NOI2004]郁闷的出纳员 (Splay)
bzoj1503,懒得复制,戳我戳我 Solution: 我知不知道我是那根筋抽了突然来做splay,调了起码\(3h+\),到第二天才改出来(我好菜啊),当做训练调错吧 一个裸的splay,没啥好说 ...
- 题解【bzoj1503 [NOI2004]郁闷的出纳员】
Description 给出一个下限 \(m\) ,要求维护以下操作 插入一个数(如果小于下限就不加) 给每个数加上一个数 给每个数减去一个数,并且删除掉 \(< m\) 的所有数 求目前第 \ ...
- [BZOJ1503] [NOI2004] 郁闷的出纳员 (treap)
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...
- BZOJ1503[NOI2004]郁闷的出纳员——treap
OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心 ...
- [luogu1486][bzoj1503][NOI2004]郁闷的出纳员【平衡树treap】
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
随机推荐
- 「日常温习」Hungary算法解决二分图相关问题
前言 二分图的重点在于建模.以下的题目大家可以清晰的看出来这一点.代码相似度很高,但是思路基本上是各不相同. 题目 HDU 1179 Ollivanders: Makers of Fine Wands ...
- TPO-15 C2 Performance on a biology exam
TPO-15 C2 Performance on a biology exam 第 1 段 1.Listen to part of a conversation between a Student a ...
- php导出excel表格的使用
网站后台有很多列表数据,常常都会有导出excel表格的需求,和大家分享一个实用的导出excel表格方法: 不多说,上代码: /** * @param array $data 要导出的数据 * @par ...
- TW实习日记:第16天
前端的样式bug实在是太太太莫名其妙了,尤其是封装好的组件,一层套一层的,根本不知道是哪一层出了问题...除了改bug就是做新功能,真想吐槽一下这个项目的留言板,根本没人会用吧...这功能实在是太老旧 ...
- leetcode-二进制手表
二进制手表顶部有 4 个 LED 代表小时(0-11),底部的 6 个 LED 代表分钟(0-59). 每个 LED 代表一个 0 或 1,最低位在右侧. 例如,上面的二进制手表读取 “3:25”. ...
- 基础数据类型-tuple
Python中,元组tuple与list类似,不同之处在于tuple的元素不能修改,tuple使用(),list使用[], (1)元组的创建使用(),需要注意的是创建包含一个元素的元组: tuple_ ...
- 第一次接触FPGA至今,总结的宝贵经验
从大学时代第一次接触FPGA至今已有10多年的时间,至今记得当初第一次在EDA实验平台上完成数字秒表.抢答器.密码锁等实验时那个兴奋劲.当时由于没有接触到HDL硬件描述语言,设计都是在MAX+plus ...
- 《剑指Offer》题四十一~题五十
四十一.数据流中的中位数 题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中 ...
- Android蓝牙开发浅谈(转)
http://www.eoeandroid.com/thread-18993-1-1.html 对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少 A ...
- 201621123034 《Java程序设计》第5周学习总结
作业05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:关键字:接口.继承.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般 ...