[NOI 2004] 郁闷的出纳员

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=1503

[算法]

         平衡树

         时间复杂度 : O(NlogN)

[代码]

        笔者的平衡树选用的是SPLAY伸展树

#include<bits/stdc++.h>
using namespace std;
#define MAXP 100010

int n,lower,x,delta;
char op[5];

struct Splay
{
        int total , root;
        Splay()
        {
                total = 0;
                root = 0;
        }
        struct Node
        {
                int father , son[2];
                int value , cnt , size;        
        } Tree[MAXP];    
        inline bool get(int x)
        {
                return Tree[Tree[x].father].son[1] == x; 
        }
        inline int getsize()
        {
                return Tree[root].size;
        }
        inline bool empty()
        {
                return (!root);
        }
        inline void update(int x)
        {
                Tree[x].size = Tree[x].cnt;
                Tree[x].size += Tree[Tree[x].son[0]].size;
                Tree[x].size += Tree[Tree[x].son[1]].size;
        }
        inline void rotate(int x)
        {
                int f = Tree[x].father , g = Tree[f].father;
                int tmpx = get(x) , tmpf = get(f);
                if (!f) return;
                Tree[f].son[tmpx] = Tree[x].son[tmpx ^ 1];
                if (Tree[x].son[tmpx ^ 1]) Tree[Tree[x].son[tmpx ^ 1]].father = f;
                Tree[x].son[tmpx ^ 1] = f;
                Tree[f].father = x;
                if (g) Tree[g].son[tmpf] = x;
                Tree[x].father = g;
                update(f);
                update(x);
        }    
        inline void splay(int x)
        {
                for (int fa = Tree[x].father; (fa = Tree[x].father); rotate(x))
                        rotate(get(x) == get(fa) ? fa : x);
                root = x;
        }
        inline void insert(int x)
        {
                if (!root)
                {
                        root = ++total;
                        Tree[total].value = x;
                        Tree[total].father = 0;
                        Tree[total].son[0] = Tree[total].son[1] = 0;
                        Tree[total].size = 1;
                        Tree[total].cnt = 1;
                        return;
                }
                int now = root;
                while (now > 0)
                {
                        if (Tree[now].value == x)
                        {
                                Tree[now].cnt++;
                                splay(now);
                                return;
                        }
                        bool tmp = x > Tree[now].value;
                        if (!Tree[now].son[tmp]) 
                        {
                                Tree[now].son[tmp] = ++total;
                                Tree[total].value = x;
                                Tree[total].father = now;
                                Tree[total].son[0] = Tree[total].son[1] = 0;
                                Tree[total].cnt = 1;
                                Tree[total].size = 1;
                                splay(total);
                                return;
                        } else now = Tree[now].son[tmp];
                }
        }
        inline int getmin()
        {
                int now = root;
                while (Tree[now].son[0]) now = Tree[now].son[0];
                splay(now);
                return Tree[now].value;
        }
        inline int query(int k)
        {
                int now = root;
                while (now > 0)
                {
                        if (k > Tree[Tree[now].son[1]].size) 
                        {
                                k -= Tree[Tree[now].son[1]].size;
                                if (k <= Tree[now].cnt) 
                                {
                                        splay(now);
                                        return Tree[now].value;        
                                }    else 
                                {
                                        k -= Tree[now].cnt;
                                        now = Tree[now].son[0];
                                }
                        } else now = Tree[now].son[1];
                }
        }
        inline int erase_min()
        {
                int now = root;
                while (Tree[now].son[0]) now = Tree[now].son[0];
                splay(now);
                Tree[Tree[root].son[1]].father = 0;
                root = Tree[now].son[1];
                int tmp = Tree[now].cnt;
                Tree[now].cnt = Tree[now].size = Tree[now].father = 0;
                Tree[now].son[0] = Tree[now].son[1] = Tree[now].value = 0;
                return tmp;
        }
} T;

int main() 
{
        
        scanf("%d%d",&n,&lower);
        int delta = 0 , cnt = 0;
        while (n--)
        {
                scanf("%s%d",&op,&x);
                if (strcmp(op,"I") == 0) 
                {
                        if (x >= lower)
                                T.insert(x - delta);
                }
                if (strcmp(op,"A") == 0) delta += x;
                if (strcmp(op,"S") == 0) delta -= x;
                while (!T.empty() && T.getmin() + delta < lower) cnt += T.erase_min();
                if (strcmp(op,"F") == 0) 
                {
                        if (T.getsize() < x) printf("-1\n");
                        else printf("%d\n",T.query(x) + delta);
                }
        }
        printf("%d\n",cnt);
        
        return 0;
    
}

 

posted @ 2018-09-09 21:22  evenbao  阅读(179)  评论(0编辑  收藏  举报