Luogu P1486 [NOI2004]郁闷的出纳员(平衡树)
题意
题目描述
\(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\)。
输出文件的最后一行包含一个整数,为离开公司的员工的总数。
输入输出样例
输入样例#1:
9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
输出样例#1:
10
20
-1
2
说明
\(I\)命令的条数不超过\(100000\)
\(A\)命令和\(S\)命令的总条数不超过\(100\)
\(F\)命令的条数不超过\(100000\)
每次工资调整的调整量不超过\(1000\)
新员工的工资不超过\(100000\)
思路
在每次\(A\)和\(S\)的时候,我们不去把每个人的工资更新,而是记录当前所有人的工资已经增加/减少了多少。假设当前已经变化了\(delta\)数量的工资,\(delta\)为正即为增加工资,\(delta\)为负即为减少工资,那么当我们新增一个工资为\(k\)的新员工时,就新增一个\(k-delta\)的档案,来消除他没有经历的工资变化。删除员工时,只删除当前工资小于\(min-delta\)的,查询第\(k\)大时,输出员工工资和\(delta\)的和,这样我们不用更新每个人的工资,照样可以完成所有操作。在这里,我用的是\(fhq\ Treap\)来完成各个操作。
AC代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e5+5;
int n,salary,delta,cnt,rt,ans;
struct Node
{
int sz,rnd,val;
int ls,rs;
#define sz(a) tree[a].sz
#define rnd(a) tree[a].rnd
#define val(a) tree[a].val
#define ls(a) tree[a].ls
#define rs(a) tree[a].rs
}tree[MAXN];
void update(int p){sz(p)=sz(ls(p))+sz(rs(p))+1;}
int new_node(int k)
{
sz(++cnt)=1;
rnd(cnt)=rand();
val(cnt)=k;
ls(cnt)=rs(cnt)=0;
return cnt;
}
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(rnd(x)<rnd(y))
{
rs(x)=merge(rs(x),y);
update(x);
return x;
}
else
{
ls(y)=merge(x,ls(y));
update(y);
return y;
}
}
void split(int now,int k,int &x,int &y)
{
if(!now) x=y=0;
else
{
if(val(now)>=k)
{
x=now;
split(rs(now),k,rs(x),y);
}
else
{
y=now;
split(ls(now),k,x,ls(y));
}
update(now);
}
}
int kth(int now,int k)
{
if(k==sz(ls(now))+1) return val(now);
if(sz(ls(now))>=k) return kth(ls(now),k);
else return kth(rs(now),k-sz(ls(now))-1);
}
int read()
{
int re=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
return re;
}
char readc()
{
char ch=getchar();
while(!isalpha(ch)) ch=getchar();
return ch;
}
int main()
{
srand(time(0));
n=read(),salary=read();
while(n--)
{
char opt=readc();int k=read();
if(opt=='I')
{
if(k<salary) continue;
k-=delta;
int x,y;
split(rt,k,x,y);
rt=merge(merge(x,new_node(k)),y);
}
else if(opt=='A') delta+=k;
else if(opt=='S')
{
delta-=k;
int x,y;
split(rt,salary-delta,x,y);
rt=x,ans+=sz(y);
}
else if(opt=='F')
{
if(k>sz(rt)) printf("%d\n",-1);
else printf("%d\n",kth(rt,k)+delta);
}
}
printf("%d",ans);
return 0;
}
Luogu P1486 [NOI2004]郁闷的出纳员(平衡树)的更多相关文章
- luogu P1486 [NOI2004]郁闷的出纳员
一万年以后终于调过了这题 这道题主要是维护一个有序的集合(吧),所以使用平衡树(我这里用\(Splay\)) 记录一个变量\(ff\)(雾),表示所有工资的变化量 对于\(I\)操作,如果初始工资大于 ...
- P1486 [NOI2004]郁闷的出纳员
P1486 [NOI2004]郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员 [STL,平衡树]
题目传送门 郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反 ...
- 洛谷 P1486 [NOI2004]郁闷的出纳员【Treap】题解+AC代码
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员(splay)
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷 P1486 [NOI2004]郁闷的出纳员
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员
Code: #include<cstdio> #include<algorithm> using namespace std; struct Node{ int s,val,t ...
- P1486 [NOI2004]郁闷的出纳员[权值线段树]
权值线段树. 我们只用维护一个人是否存在,以及他当前排名,而不关心工资的具体值,这个可以直接算. 不难发现,如果不考虑新的员工,所有员工的工资的差值是不变的. 而加进来一个新的员工时,其工资为\(x\ ...
- [NOI2004]郁闷的出纳员(平衡树)
[NOI2004]郁闷的出纳员 题目链接 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的 ...
随机推荐
- Python: map和reduce
可以先google一篇论文:MapReduce: SImplified Data Processing on Large Clusters 1. map map()函数接收2个参数:一个是函数,一个是 ...
- 分析post与json
寻找登录的post地址 在form表单中寻找action对应的url地址 post的数据是input标签中name的值作为键,真正的用户名密码作为值的字典,post的url地址就是action对应的u ...
- SGI STL rope
rope实现的接口可以参考这里. rope是可伸缩的string实现: 它们被设计为用于把string看作一个整体的高效操作 . 比如赋值.串联和子串的操作所花的时间差不多不依赖字符串的长度.与C的字 ...
- 建立ftp服务器和客户端
参考:https://www.cnblogs.com/judes/p/9546447.html 补充: 权限设置:如下所示,如果需要上传文件需要勾选write权限,需要在文件中添加内容勾选append ...
- multiprocessing多进程(31-04)创建进程的两种方式
一个进程可以寄生多个线程. CPU核数与进程个数是统一的, 若进程多于核数,那么只有等待上一进程执行完才能被执行. ------------------第一种进程创建方式--------------- ...
- 20.multi_case03
# 多线程 import threading import time class myThread(threading.Thread): def __init__(self, threadID, na ...
- flexbox属性速览及常见布局实现
CSS3 弹性盒子(Flex Box)弹性盒子是即 CSS2 浮动布局后, CSS3 的一种新的布局模式. CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同 ...
- google浏览器插件开发
官方开发文档 随便找个文件夹新建插件所需文件 目录结构 pluginName manifest.json(必须) 一个manifest文件 *.htm ...
- eclipse 克隆 https 地址的 Git 仓库报错:cannot open git-upload-pack
解决方法:Window >Preferences >Team>Git>User settings点击Add Entry设置key:http.sslVerify value:fa ...
- Caffe系列4——基于Caffe的MNIST数据集训练与测试(手把手教你使用Lenet识别手写字体)
基于Caffe的MNIST数据集训练与测试 原创:转载请注明https://www.cnblogs.com/xiaoboge/p/10688926.html 摘要 在前面的博文中,我详细介绍了Caf ...