NKOJ 3776 工资管理
问题描述
何老板的公司有n名员工,编号1到n。一开始所有员工的工资都是0。根据何老板的心情好坏,可能出现下列两种针对员工工资的操作:
1.U x y 改工资操作:何老板将第x号员工的工资改成了y;
2.Z x y 减工资操作:何老板生气了,他想选出x个员工,并将他们的工资全都减去1。何老板想知道,他能否一口气进行y次这样的减工资操作。能输出TAK,否则输出NIE。注意,员工的工资不能为
负。对于每个减工资的操作,何老板只是在心里想想,口头上说说,吓唬吓唬大家,解解闷气,他并不会真正执行。即不会对任何人的工资进行修改。
输入格式
第一行包含两个正整数n,m,分别表示员工的人数和操作次数。 接下来m行,每行一个操作,形式如题面所述。
输出格式
包含若干行,对于每个减工资操作,若可行,输出TAK,否则输出NIE。
样例输入 1
3 8
U 1 5
U 2 7
Z 2 6
U 3 1
Z 2 6
U 2 2
Z 2 6
Z 2 1
样例输出 1
NIE
TAK
NIE
TAK
样例输入 2
13 17
U 1 12
Z 1 9
Z 1 5
Z 4 7
U 7 18
Z 1 1
Z 1 8
U 6 4
U 1 9
U 3 13
Z 5 2
U 7 8
U 4 20
U 7 14
Z 6 1
Z 3 2
Z 8 7
样例输出 2
TAK
TAK
NIE
TAK
TAK
NIE
NIE
TAK
NIE
提示
对于30%的数据:1<=n,m<=1000 对于100%的数据:1<=n,m<=200000
1<=x<=n,0<=y<=10^9,1<=y<=10^9。
来源
改编自POI2015 Logistyka
显然,思维量主要在Z操作上。对于Z操作,首先容易想到,如果有工资大于等于y的人,那么他们在这y次操作中都应该被选到,因为选肯定比不选更优。假设我们找到了工资大于等于y的人数,接下来只需要考虑x个位置中剩下的部分怎么选。
不妨设每次剩下需要选的人数为z。我们首先会想到:如果工资低于y的人的工资总数都比z*y要小,那么这个操作显然不能完成。这是一个必要条件,然而这也同样是一个充分条件!
下面略微说明一下为什么这是一个充分条件:
在剩下的人的工资总数不低于z*y的条件下,假设存在这样一种情况,在完成第y次操作前的某一次选不出z个满足条件的人(即,原工资小于y,操作若干次后工资大于0)。由于现在存在的满足条件的人数小于z,且剩下的人的工资总数不低于z*y,分析得一定存在某人的原工资不低于y,与条件矛盾。
所以我们现在只需要知道下列数据:
1.工资不低于某个值的人数总和;
2.工资小于某个值的人的工资总和。
离散化之后用树状数组维护即可。
#include<stdio.h>
#include<algorithm>
#define ll long long
#define MAXN 200005
using namespace std;
struct node{int k,x,y;}data[MAXN];
int N,M,w[MAXN],e[MAXN];int C[MAXN];ll D[MAXN];
void Modify(int x,int k){for(int i=x;i<=M;i+=(i&-i))C[i]+=k,D[i]+=1ll*k*w[x];}
ll Tot,Cnt;
void GetSum(int x)
{
int i;Cnt=Tot=0;
for(i=x;i;i-=(i&-i))Cnt+=C[i],Tot+=D[i];
}
int main()
{
int i,a,b,R;
char c[3];
scanf("%d%d",&N,&M);
w[1]=0;
for(i=1;i<=M;i++)
{
scanf("%s%d%d",&c,&a,&b);
if(c[0]=='U')data[i].k=0;
else data[i].k=1;
w[i+1]=b;data[i].x=a;data[i].y=b;
}
Modify(1,N);
M++;
sort(w+1,w+M+1);
R=unique(w+1,w+M+1)-w;
M--;
for(i=1;i<=M;i++)
{
if(data[i].k==0)
{
a=lower_bound(w+1,w+R,e[data[i].x])-w;
Modify(a,-1);
a=lower_bound(w+1,w+R,data[i].y)-w;
Modify(a,1);
e[data[i].x]=data[i].y;
}
else
{
a=lower_bound(w+1,w+R,data[i].y)-w;
GetSum(a-1);
if(Tot>=1ll*(data[i].x-N+Cnt)*data[i].y)puts("TAK");
else puts("NIE");
}
}
}