出纳员没郁闷,我倒郁闷了。
Debug了3个小时?!
首先,我们发现,对于增加和减工资操作是全局的性质的。
所以我们可以用一个变量来维护这个操作。
怎么删除呢?
我们可以找到第一个大于退出工资的人,把他这人提到根上去。
然后小于退出工资的人全部集中在了根节点的左子树。
可以先插入一个极大的虚根维护这个问题,否则全部都小于退出工资的情况不好搞。
询问查询的是第几大,不是第几小~
#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const int maxm=120000;
int f[maxm],ch[maxm][2];
int size[maxm];
int sz,root;
int val[maxm];
int n,minx;
int delet=0;
inline void updata(int x)
{
if(x)
{
size[x]=1;
if(ch[x][0]) size[x]+=size[ch[x][0]];
if(ch[x][1]) size[x]+=size[ch[x][1]];
}
return;
}
inline bool get(int x)
{
return ch[f[x]][1]==x;
}
inline void rota(int x)
{
int fa=f[x],ffa=f[fa],which=get(x);
bool fx=get(fa);
ch[fa][which]=ch[x][which^1];
f[ch[fa][which]]=fa;
ch[x][which^1]=fa;
f[fa]=x;
f[x]=ffa;//关系变化
if(ffa)
ch[ffa][fx]=x;//认爷做父
updata(fa),updata(x);
}
inline void splay(int x)
{
for (int fa;(fa=f[x])!=0;rota(x))
if (f[fa]!=0)
rota(get(fa)==get(x)?fa:x);
root=x;
}
inline void insert(int x)
{
int now=root,fa=0;
while(1)
{
fa=now;
now=ch[fa][val[now]<x];
if(now==0)
{
sz++;
ch[sz][0]=ch[sz][1]=0;
val[sz]=x,size[sz]=1;
f[sz]=fa,ch[fa][val[fa]<x]=sz;
updata(fa);
splay(sz);
return;
}
}
}
inline int findx(int x)
{
int now=root;
while(1)
{
if(x==size[ch[now][0]]+1) return val[now];
else if(x<=size[ch[now][0]]+1) now=ch[now][0];
else
{
x-=size[ch[now][0]]+1;
now=ch[now][1];
}
}
}
int del(int now,int k)
{
if(!now) return 0;
if(val[now]>=k)
{
int d=del(ch[now][0],k);
if(!d) return now;
else return d;
}
else return del(ch[now][1],k);
}
inline int read()
{
int x=0;char ch=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x;
}
int main()
{
root=1,sz=1,size[root]=1,val[root]=1e8;
n=read(),minx=read();
char s[3];
int ans=0;
//printf("%d",t[root].size);
delet=minx;
for(int i=1,k;i<=n;i++)
{
scanf("%s",s);
k=read();
if(s[0]=='I')
{
if(k<minx) continue;
insert(k-delet);
}
if(s[0]=='A')
delet+=k;
if(s[0]=='S')
{
delet-=k;
int xx=del(root,minx-delet);
splay(xx);
ans+=size[ch[root][0]];
size[root]-=size[ch[root][0]];
ch[root][0]=0;
}
if(s[0]=='F')
{
int f=0;
if(size[root]-1<k) f=-1,printf("%d\n",f);
else
f=findx(size[root]-k),printf("%d\n",f+delet);
}
}
printf("%d",ans);
return 0;
}