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;
        
    }
  • 相关阅读:
    Time Zone 【模拟时区转换】(HDU暑假2018多校第一场)
    HDU 1281 棋盘游戏 【二分图最大匹配】
    Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
    Codeforces Round #527 (Div. 3) D2. Great Vova Wall (Version 2) 【思维】
    Codeforces Round #527 (Div. 3) D1. Great Vova Wall (Version 1) 【思维】
    Codeforces Round #528 (Div. 2, based on Technocup 2019 Elimination Round 4) C. Connect Three 【模拟】
    Avito Cool Challenge 2018 E. Missing Numbers 【枚举】
    Avito Cool Challenge 2018 C. Colorful Bricks 【排列组合】
    005 如何分析问题框架
    004 如何定义和澄清问题
  • 原文地址:https://www.cnblogs.com/evenbao/p/9615180.html
Copyright © 2011-2022 走看看