[NOI2004] 郁闷的出纳员
题目链接:戳我
还是splay啦!但是有一点不同的是,这次有加减操作了。但是splay不支持怎么办啊qwq
转化呗。我们开一个变量cur来记录从开始到现在一共减去了多少钱,然后插入查询等等操作时把它加上或者减去就行了。
注意开始不要插入极小值,因为那个小于min值,是不合法的啦qwq会对后面的操作产生影响。qwq
具体细节看代码吧qwq
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 100010
using namespace std;
int n,m,root,tot,cur,sum,ans,mm;
struct Node{int cnt,ff,son,val,ch[2];}t[MAXN<<1];
inline void push_up(int x){t[x].son=t[x].cnt+t[t[x].ch[0]].son+t[t[x].ch[1]].son;}
inline void rotate(int x)
{
int y=t[x].ff;
int z=t[y].ff;
int k=t[y].ch[1]==x;
t[z].ch[t[z].ch[1]==y]=x; t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y; t[y].ff=x;
push_up(y),push_up(x);
}
inline void splay(int x,int goal)
{
while(t[x].ff!=goal)
{
int y=t[x].ff;
int z=t[y].ff;
if(z!=goal)
((t[z].ch[0]==y)^(t[y].ch[0]==x))?rotate(x):rotate(y);
rotate(x);
}
if(goal==0) root=x;
}
inline void insert(int x)
{
int u=root,ff=0;
while(u&&t[u].val!=x)
ff=u,u=t[u].ch[t[u].val<x];
if(u) t[u].cnt++;
else
{
u=++tot;
if(ff) t[ff].ch[t[ff].val<x]=u;
t[u].cnt=t[u].son=1;
t[u].ff=ff,t[u].val=x;
}
splay(u,0);
}
inline void find(int x)
{
int u=root;
if(!u) return;
while(t[u].ch[t[u].val<x]&&t[u].val!=x) u=t[u].ch[t[u].val<x];
splay(u,0);
}
inline int Next(int x,int f)
{
find(x);
int u=root;
if((!f&&t[u].val<=x)||(f&&t[u].val>=x)) return u;
u=t[u].ch[f];
while(t[u].ch[f^1]) u=t[u].ch[f^1];
return u;
}
inline int k_th(int x)
{
int u=root;
if(t[u].son<x||x<=0) return 0;
for(;;)
{
int y=t[u].ch[0];
if(x>t[y].son+t[u].cnt) x-=t[y].son+t[u].cnt,u=t[u].ch[1];
else if(x<=t[y].son) u=t[u].ch[0];
else return t[u].val;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
insert(2147483627/3);
for(int i=1;i<=n;i++)
{
char op;
int x;
cin>>op;scanf("%d",&x);
if(op=='I')
{
if(x<m) continue;
else insert(cur+x),sum++;
}
else if(op=='A')
cur-=x;
else if(op=='S')
{
cur+=x;
int now_x=Next(m+cur,1);
splay(now_x,0);
ans+=t[t[root].ch[0]].son;
sum-=t[t[root].ch[0]].son;
t[t[root].ch[0]].son=0;
t[t[root].ch[0]].cnt=0;
t[root].ch[0]=0;
push_up(root);
}
else if(op=='F')
{
if(sum<x||t[root].son<x) printf("-1\n");
else
{
int now_x=k_th(sum-x+1);
printf("%d\n",now_x-cur);
}
}
}
printf("%d\n",ans);
return 0;
}