zoukankan      html  css  js  c++  java
  • [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
    ");
                else
                {
                    int now_x=k_th(sum-x+1);
                    printf("%d
    ",now_x-cur);
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    最大流最小割
    最大权闭合图
    凸包,多边形面积,线段在多边形内的判定。
    模线性方程
    ZOJ Monthly, August 2014
    nenu contest2
    2014 Multi-University Training Contest 10
    Codeforces Round #262 (Div. 2)
    nenu contest
    poj 2299 求逆序数
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10283576.html
Copyright © 2011-2022 走看看