P1486 [NOI2004]郁闷的出纳员
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。
输出文件的最后一行包含一个整数,为离开公司的员工的总数。
降低或提高工资时, 把 \(Treap\) 树中全部节点拿出, 修改后再放回,在时间上不太能够接受(虽然这题数据是可以的), 我们用一个变量 \(lazy\) 维护从刚开始一共变化了多少工资, 所以几个操作转化为如下操作:
1.来新人: 由于有一个基础变化 \(lazy\) 新人享受不到, 一个人只能享受加入公司之后的工资变化, 所以我们向 \(Treap\) 中加入 \(x - lazy\)
2.加工资: 并不会影响员工的走留, 直接累计到 \(lazy\) 即可
3.减工资: 先更新 \(lazy\) 。因为所有员工的最低工资是一样的, 所以要走总是工资最少的。 我们不断查询工资最少的员工, 看是否留下, 若是不留则删除继续看下一个工资多一点的走不走。 一旦发现有一个不走了, 那么后面的都是工资更多的, 也就不会走了。
4.查询第k小: 注意是第k小。直接查询即可, 查出来加上 \(lazy\) 即为答案
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int RD(){
int flag = 1, out = 0;char c = getchar();
while(c < '0' || c > '9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 1000019, INF = 1e9 + 19;
int ch[maxn][2];
int size[maxn], cnt[maxn];
int val[maxn], dat[maxn];
int root, tot;
int New(int v){
val[++tot] = v;dat[tot] = rand();
size[tot] = cnt[tot] = 1;
return tot;
}
void pushup(int id){size[id] = size[ch[id][0]] + size[ch[id][1]] + cnt[id];}
void build(){
root = New(-INF);
ch[root][1] = New(INF);
pushup(root);
}
void Rotate(int &id, int d){
int temp = ch[id][d ^ 1];
ch[id][d ^ 1] = ch[temp][d];
ch[temp][d] = id;
id = temp;
pushup(ch[id][d]), pushup(id);
}
void insert(int &id, int v){
if(!id){id = New(v);return ;}
if(val[id] == v){cnt[id]++;pushup(id);return ;}
int d = v < val[id] ? 0 : 1;
insert(ch[id][d], v);
if(dat[ch[id][d]] > dat[id])Rotate(id, d ^ 1);
pushup(id);
}
void Remove(int &id, int v){
if(!id)return ;
if(val[id] == v){
if(cnt[id] > 1){cnt[id]--;pushup(id);return ;}
if(ch[id][0] || ch[id][1]){
if(!ch[id][1] || dat[ch[id][0]] > dat[ch[id][1]]){
Rotate(id, 1);
Remove(ch[id][1], v);
}
else Rotate(id, 0), Remove(ch[id][0], v);
pushup(id);
}
else id = 0;
return ;
}
v < val[id] ? Remove(ch[id][0], v) : Remove(ch[id][1], v);
pushup(id);
}
int get_val(int id, int rank){
if(!id)return INF;
if(size[ch[id][0]] >= rank)return get_val(ch[id][0], rank);
else if(size[ch[id][0]] + cnt[id] >= rank)return val[id];
else return get_val(ch[id][1], rank - size[ch[id][0]] - cnt[id]);
}
int na, minn;
int lazy, c, sum;
int main(){
na = RD();minn = RD();
build();
char cmd;int x;
for(int i = 1;i <= na;i++){
cin>>cmd;
if(cmd == 'I'){
x = RD();
if(x >= minn){
insert(root, x - lazy);
sum++;
}
}
else if(cmd == 'A'){
lazy += RD();
}
else if(cmd == 'S'){
x = RD();
lazy -= x;
if(sum == 0)continue;
bool flag = 1;
while(flag){
int MIN = get_val(root, 2);
if(MIN + lazy < minn)Remove(root, MIN), c++, sum--;
else flag = 0;
if(sum == 0)break;
}
}
else if(cmd == 'F'){
x = RD();
if(sum < x)printf("-1\n");
else printf("%d\n", get_val(root, size[root] - x) + lazy);
}
}
printf("%d\n", c);
return 0;
}
P1486 [NOI2004]郁闷的出纳员的更多相关文章
- Luogu P1486 [NOI2004]郁闷的出纳员(平衡树)
P1486 [NOI2004]郁闷的出纳员 题意 题目描述 \(OIER\)公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员 [STL,平衡树]
题目传送门 郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反 ...
- 洛谷 P1486 [NOI2004]郁闷的出纳员【Treap】题解+AC代码
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员(splay)
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷 P1486 [NOI2004]郁闷的出纳员
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- luogu P1486 [NOI2004]郁闷的出纳员
一万年以后终于调过了这题 这道题主要是维护一个有序的集合(吧),所以使用平衡树(我这里用\(Splay\)) 记录一个变量\(ff\)(雾),表示所有工资的变化量 对于\(I\)操作,如果初始工资大于 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员
Code: #include<cstdio> #include<algorithm> using namespace std; struct Node{ int s,val,t ...
- P1486 [NOI2004]郁闷的出纳员[权值线段树]
权值线段树. 我们只用维护一个人是否存在,以及他当前排名,而不关心工资的具体值,这个可以直接算. 不难发现,如果不考虑新的员工,所有员工的工资的差值是不变的. 而加进来一个新的员工时,其工资为\(x\ ...
- BZOJ 1503: [NOI2004]郁闷的出纳员
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 10526 Solved: 3685[Submit][Stat ...
随机推荐
- 使用Spring boot 嵌入的tomcat不能启动: Unregistering JMX-exposed beans on shutdown
新建一个spring boot的web项目,运行之后控制台输出“Unregistering JMX-exposed beans on shutdown”,tomcat也没有运行.寻找原因,看了下pom ...
- Scrum meeting报告
Scrum Meeting报告 要点: 讨论XueBa系统已有的和待实现的功能 短期内的任务分配 初步确定小组成员在第一轮迭代开发中任务 一. XueBa系统已有的和待实现的功能 项目完成情 ...
- 2018-2019-20172329 《Java软件结构与数据结构》第八周学习总结
2018-2019-20172329 <Java软件结构与数据结构>第八周学习总结 现在对于我而言,最珍贵的是时间,感觉自己在时间飞逝的时候真的挽留不住什么,只能怒发冲冠的让自己疯狂的学习 ...
- 08慕课网《进击Node.js基础(一)》事件events
引用events模块中的EventEmitter 事件的监听和发射 相同的事件发射数量有限,可以通过setMaxListeners设置峰值 var EventEmitter = require('ev ...
- C++:内存分区
前言:最近正在学习有关static的知识,发觉对C++的内存分区不是很了解,上网查了很多资料,遂将这几天的学习笔记进行了简单整理,发表在这里 • 栈区(stack):主要用来存放函数的参数以及局部变量 ...
- 寒假作业第二篇随笔(A+B)
Github链接:https://github.com/heihuifei/object-oriented A+B Format (20) Calculate a + b and output the ...
- What is ASP.NET SignalR
什么是ASP.NET SignalR ASP.NET SignalR是ASP.NET开发人员的新库,它使得为应用程序添加实时Web功能变得非常简单. 什么是“实时网络”功能?它能够让您的服务器端代码实 ...
- Django Model基础操作
关于设计django model django为我们集成了ORM对数据库进行操作,我们只需要进行定义model,django就会自动为我们创建表,以及表之间的关联关系 创建好一个django项目-首先 ...
- 团队作业4--第一项目冲刺3(Aplpha)
1.会议 第三次会议: ①:总结前两天出现的问题 ②:总结前端学习的心得 ③:安排后两天任务 2.任务安排 3.任务分解图 4.燃尽图 5.适当的项目程序/模块的最新(运行)截图 6.心得 组员之间要 ...
- MapReduce编程之Semi Join多种应用场景与使用
Map Join 实现方式一 ● 使用场景:一个大表(整张表内存放不下,但表中的key内存放得下),一个超大表 ● 实现方式:分布式缓存 ● 用法: SemiJoin就是所谓的半连接,其实仔细一看就是 ...