/**//* 题意:实现对所有员工工资加x、减x(如果减了后发现低于最低工资,则离开) 并查询第k大的工资 这里用树状数组 插入容易实现 删除时注意for(int i = 1;;i++) i从小到大,则c[i]存的就是工资为i时的人数了! 还有是整个线段操作,所以用delta标记,会快很多!! 插入时,就插入 x-delta+INF 加上INF避免变为负数了~ 还有findK() 其实是用二分不断逼近 保持着cnt<K 则最后ans+1即为答案了 */ #include<cstdio> #include<cstring>
const int MAX_VAL = 300000,INF = 100000;
int c[MAX_VAL+5]; int delta;
inline int lowbit(int x){return x&(-x);}
int sum(int p) { int ans = 0; while(p>0) { ans+=c[p]; p-=lowbit(p); } return ans; } void update(int p,int x) { while(p<=MAX_VAL) { c[p]+=x; p+=lowbit(p); } } int findK(int K) { int ans = 0,cnt = 0; for(int i=19;i>=0;i--) { ans+=(1<<i); if(ans>=MAX_VAL||cnt+c[ans]>=K)ans-=(1<<i); else cnt+=c[ans]; } return ans+1; } int main() { int Q,Min; while(~scanf("%d%d",&Q,&Min)) { memset(c,0,sizeof(c)); delta = 0; int tot = 0,del = 0; while(Q--) { char op; int x; scanf(" %c%d",&op,&x); if(op=='I'){ if(x<Min)continue; update(x-delta+INF,1); tot++; } else if(op=='S') { delta-=x; int tmp = sum(Min-1-delta+INF); tot-=tmp; del+=tmp; for(int i=1;i<=Min-1-delta+INF;i++) { if(c[i]==0)continue; update(i,-c[i]); //因为是从小到大删除,这时的c[i]其实就是工资为i的实际人数! } } else if(op=='A')delta+=x; else { if(x>tot)puts("-1"); else printf("%d\n",findK(tot-x+1)+delta-INF); } } printf("%d\n",del); } return 0; }
|
|
常用链接
随笔分类
Links
搜索
最新评论
|
|