 /**//*
題意:實現對所有員工工資加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
搜索
最新評論

|
|