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]郁闷的出纳员的更多相关文章

  1. Luogu P1486 [NOI2004]郁闷的出纳员(平衡树)

    P1486 [NOI2004]郁闷的出纳员 题意 题目描述 \(OIER\)公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作 ...

  2. 洛谷P1486 [NOI2004]郁闷的出纳员 [STL,平衡树]

    题目传送门 郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反 ...

  3. 洛谷 P1486 [NOI2004]郁闷的出纳员【Treap】题解+AC代码

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  4. 洛谷P1486 [NOI2004]郁闷的出纳员(splay)

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  5. 洛谷 P1486 [NOI2004]郁闷的出纳员

    题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...

  6. luogu P1486 [NOI2004]郁闷的出纳员

    一万年以后终于调过了这题 这道题主要是维护一个有序的集合(吧),所以使用平衡树(我这里用\(Splay\)) 记录一个变量\(ff\)(雾),表示所有工资的变化量 对于\(I\)操作,如果初始工资大于 ...

  7. 洛谷P1486 [NOI2004]郁闷的出纳员

    Code: #include<cstdio> #include<algorithm> using namespace std; struct Node{ int s,val,t ...

  8. P1486 [NOI2004]郁闷的出纳员[权值线段树]

    权值线段树. 我们只用维护一个人是否存在,以及他当前排名,而不关心工资的具体值,这个可以直接算. 不难发现,如果不考虑新的员工,所有员工的工资的差值是不变的. 而加进来一个新的员工时,其工资为\(x\ ...

  9. BZOJ 1503: [NOI2004]郁闷的出纳员

    1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 10526  Solved: 3685[Submit][Stat ...

随机推荐

  1. TeamWork#3,Week5,Bing Input Method vs Sogou Input Method

    现在电脑上用五笔的用户越来越少了,好的拼音输入法也是难求.必应输入法的前身英库拼音输入法来自微软亚洲研究院的多项基础研究成果.最新的必应输入法不仅保留了英库拼音输入法的各项优势,还结合了必应的搜索体验 ...

  2. iOS开发学习-nonatomic和atomic的区别

    nonatomic是非原子性的,也就是给线程不加原子锁,这样的代码运行效率会更高一点,例如: @property (nonatomic,copy)NSString *userName; @proper ...

  3. python learning OOP1.py

    class Student(object): # 构造函数 # 第一个参数永远是 self 表示一个实例本身,但是传参的时候不需要传 # 在Python中,实例的变量名如果以__开头,就变成了一个私有 ...

  4. 软工网络15团队作业8——Beta阶段敏捷冲刺(Day2)

    提供当天站立式会议照片一张 每个人的工作 1.讨论项目每个成员的昨天进展 赵铭: 根据计划安排,继续学习数据库. 吴慧婷:做Beta阶段的计划,并为界面设计寻找素材,学习界面优化. 陈敏: 根据任务, ...

  5. SQL Server学习记录之获取每月每季度每年第一天和最后一天

    DECLARE@dtdatetime SET@dt=GETDATE() DECLARE@numberint --1.指定日期该年的第一天或最后一天 --A. 年的第一天 SELECTCONVERT() ...

  6. [转帖] .net 2.1 是 LTS长期支持版本.

    [翻译] .NET Core 2.1 发布   原文: Announcing .NET Core 2.1 我们很高兴可以发布 .NET Core 2.1.这次更新包括对性能的改进,对运行时和工具的改进 ...

  7. Shopping Bands Rank & SBR

    Shopping Bands Rank SBR https://www.guiderank.org/index.html Nike Air Zoom Pegasus 34 http://www.shi ...

  8. List,Set和Map详解及其区别和他们分别适用的场景

    Java中的集合包括三大类,它们是Set(集).List(列表)和Map(映射),它们都处于java.util包中,Set.List和Map都是接口,它们有各自的实现类.Set的实现类主要有HashS ...

  9. iOS 一些常见问题

    1.屏幕横屏时 xib上拖拉的控件不会跟着横过来: 是因为在主文件面里的 main interface 方框里的main 没有删除: 2.运行出现你没有权限 : 清理一下: 3.将对象转成字符串: / ...

  10. mybatis中@Param的使用

    @Param:当映射器方法需要多个参数时,这个注解可以被用于:给映射器方法中的每个参数来取一个名字.否则,多参数将会以它们的顺序位置和SQL语句中的表达式进行映射,这是默认的.    语法要求:若使用 ...