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是一个正整数。
在初始时,可以认为公司里一个员工也没有。
I命令的条数不超过100000
A命令和S命令的总条数不超过100
F命令的条数不超过100000
每次工资调整的调整量不超过1000
新员工的工资不超过100000
Output
输出行数为F命令的条数加一。
对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,
如果k大于目前员工的数目,则输出-1。
输出文件的最后一行包含一个整数,为离开公司的员工的总数。
题解:
因为是对所有员工加减一个值,所以用一个变量记录即可
对于I命令,直接插入即可,提前判断一下这个员工是不是需要插入,而且不计入离开公司的员工
对于A命令,直接让变量+k
对于S命令,直接让变量-k,并且判断有多少个人需要离开公司
对于F命令,查询第k大
全是模板操作
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int MAXN = 2e5+10;
const int MOD = 998244353;
struct node{
int son[2],fa,val,sz;
inline void Init(int f,int v){ fa=f; val=v; sz=1; son[0]=son[1]=0; }
}t[MAXN];
int root,tot;
inline int id(int x){ return x==t[t[x].fa].son[1]; }
inline void pushup(int x){ t[x].sz=t[t[x].son[0]].sz+t[t[x].son[1]].sz+1; }
inline void rotate(int x){
int y=t[x].fa,z=t[y].fa,k=id(x);
t[z].son[id(y)]=x; t[x].fa=z;
t[y].son[k]=t[x].son[k^1]; t[t[x].son[k^1]].fa=y;
t[x].son[k^1]=y; t[y].fa=x;
pushup(y); pushup(x);
}
inline void splay(int x,int pos){
while(t[x].fa!=pos){
int y=t[x].fa,z=t[y].fa;
if(z!=pos) id(x)==id(y) ? rotate(y):rotate(x);
rotate(x);
}
if(!pos) root=x;
}
inline void Insert(int x){
int u=root; t[u].sz++;
while(t[u].son[x>t[u].val]) u=t[u].son[x>t[u].val],t[u].sz++;
t[u].son[x>t[u].val] = ++tot; t[tot].val=x;
t[tot].sz=1; t[tot].fa=u; splay(tot,0);
}
inline int Find_min(){
int u=root;
while(t[u].son[0]) u=t[u].son[0];
return u;
}
inline int kth(int x){
int u=root;
while(1){
if(t[t[u].son[0]].sz>=x) u=t[u].son[0];
else{
x -= t[t[u].son[0]].sz+1;
if(!x) return u;
u = t[u].son[1];
}
}
}
inline void del(int u){
splay(u,0);
if(!t[u].son[0]) root=t[u].son[1],t[t[u].son[1]].fa=0;
else if(!t[u].son[1]) root=t[u].son[0],t[t[u].son[0]].fa=0;
else{
int v=t[u].son[0]; t[v].fa=0;
while(t[v].son[1]) v = t[v].son[1];
splay(v,0);
t[v].son[1] = t[u].son[1]; t[t[u].son[1]].fa=v;
pushup(v);
}
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
int Q,m,x,cnt=0,sum=0,res=0; char op[2]; scanf("%d%d",&Q,&m);
root=tot=1; t[1].val=INT_MAX; t[1].sz=1;
while(Q--){
scanf("%s%d",op,&x);
if(op[0]=='I'){
if(x<m) continue;
cnt++; Insert(x-sum);
}else if(op[0]=='A'){
sum += x;
}else if(op[0]=='S'){
sum -= x;
while(1){
int u=Find_min();
if(t[u].val+sum < m) del(u),res++;
else break;
}
}else if(op[0]=='F'){
if(x>cnt-res) { puts("-1");continue; }
int u=kth(cnt-res-x+1);
printf("%d\n",t[u].val+sum);
}
}
printf("%d\n",res);
return 0;
}