[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;
}
posted @ 2019-01-17 17:48  风浔凌  阅读(140)  评论(0编辑  收藏  举报