zoukankan      html  css  js  c++  java
  • [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
    ");
                            else printf("%d
    ",T.query(x) + delta);
                    }
            }
            printf("%d
    ",cnt);
            
            return 0;
        
    }
  • 相关阅读:
    union 和 union all的区别
    JDBC中PreparedStatement相比Statement的好处
    25个经典的Spring面试问答
    MySQL 事务
    漫谈Linux下的音频问题(转)
    监控 Linux 性能的 18 个命令行工具(转)
    在终端中用默认程序打开文件(转)
    【转】使程序在Linux下后台运行 (关掉终端继续让程序运行的方法)
    Getting Started with Amazon EC2 (1 year free AWS VPS web hosting)
    压缩解压命令小结
  • 原文地址:https://www.cnblogs.com/evenbao/p/9615180.html
Copyright © 2011-2022 走看看