zoukankan      html  css  js  c++  java
  • 【BZOJ 3224】 普通平衡树

    【题目链接】

              点击打开链接

    【算法】

             本题是Splay模板题,值得一做!

    【代码】

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 100000
    
    int N,opt,x;
    
    template <typename T> inline void read(T &x) {
            int f = 1; x = 0;
            char c = getchar();
            for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
            for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
            x *= f;
    }
    
    template <typename T> inline void write(T x) {
        if (x < 0) { putchar('-'); x = -x; }
        if (x > 9) write(x/10);
        putchar(x%10+'0');
    }
    
    template <typename T> inline void writeln(T x) {
        write(x);
        puts("");
    }
    
    struct Splay {
            int root,total;
            struct Node {
                    int fa,son[2],val,cnt,size;
            } Tree[MAXN+10];
            bool get(int x) {
                    return Tree[Tree[x].fa].son[1] == x;
            }
            inline void new_node(int index,int f,int x) {
                    Tree[index].fa = f;
                    Tree[index].son[0] = Tree[index].son[1] = 0;
                    Tree[index].val = x;
                    Tree[index].cnt = Tree[index].size = 1;
            }
            inline void update(int index) {
                    Tree[index].size = Tree[index].cnt;
                    Tree[index].size += Tree[Tree[index].son[0]].size;
                    Tree[index].size += Tree[Tree[index].son[1]].size;
            }
            inline void rotate(int x) {
                    int f = Tree[x].fa,g = Tree[f].fa,
                        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]].fa = f;
                    Tree[x].son[tmpx^1] = f;
                    Tree[f].fa = x;
                    Tree[x].fa = g;
                    if (g) Tree[g].son[tmpf] = x;
                    update(f);
                    update(x);            
            }
            inline void splay(int x) {
                    int f;
                    for (f = Tree[x].fa; (f = Tree[x].fa); rotate(x)) 
                            rotate((get(x) == get(f)) ? (f) : (x));
                    root = x;
            }
            inline void Insert(int x) {
                    int index = root;
                    bool tmp;
                    if (!root) {
                            new_node(++total,0,x);
                            root = total;
                            return;
                    }
                    while (true) {
                            if (Tree[index].val == x) {
                                    ++Tree[index].cnt;
                                    splay(index);
                                    return;
                            }
                            tmp = Tree[index].val < x;
                            if (!Tree[index].son[tmp]) {
                                    new_node(++total,index,x);
                                    Tree[index].son[tmp] = total;
                                    splay(total);
                                    return;
                            } else index = Tree[index].son[tmp];
                    }
            }
            inline int query_max(int index) {
                    while (true) {
                            if (!Tree[index].son[1]) return index;
                            index = Tree[index].son[1];
                    }
            }
            inline int query_min(int index) {
                    while (true) {
                            if (!Tree[index].son[0]) return index;
                            index = Tree[index].son[0];
                    }
            }
            inline void join(int x,int y) {
                    int pos = query_max(x);
                    splay(pos);
                    Tree[pos].son[1] = y;
                    Tree[y].fa = pos;    
            }
            inline void erase(int x) {
                    int index = root;
                    bool tmp;
                    while (true) {
                            if (Tree[index].val == x) {
                                    if (Tree[index].cnt > 1) {
                                            --Tree[index].cnt;
                                            splay(index);
                                            return;
                                    }
                                    splay(index);
                                    break;
                            }
                            tmp = Tree[index].val < x;
                            index = Tree[index].son[tmp];
                    }        
                    if ((!Tree[index].son[0]) && (!Tree[index].son[1])) {
                            root = 0;
                            return;
                    }
                    if (!Tree[index].son[0]) {
                            root = Tree[index].son[1];
                            Tree[root].fa = 0;
                            return;
                    }
                    if (!Tree[index].son[1]) {
                            root = Tree[index].son[0];
                            Tree[root].fa = 0;
                            return;
                    }
                    join(Tree[index].son[0],Tree[index].son[1]);
            }
            inline int query_rank(int x) {
                    int index = root,ans=1;
                    while (true) {
                            if (Tree[index].val <= x) {
                                    ans += Tree[Tree[index].son[0]].size;
                                    if (Tree[index].val == x) {
                                            splay(index);
                                            return ans;
                                    }
                                    ans += Tree[index].cnt;
                                    index = Tree[index].son[1];
                            } else index = Tree[index].son[0];
                    }
            } 
            inline int rank(int x) {
                    int index = root;
                    while (true) {
                            if (x <= Tree[Tree[index].son[0]].size) index = Tree[index].son[0];
                            else {
                                    x -= Tree[Tree[index].son[0]].size;
                                    if (x <= Tree[index].cnt) {
                                            splay(index);
                                            return Tree[index].val;        
                                    }
                                    x -= Tree[index].cnt;
                                    index = Tree[index].son[1];
                            }
                    }
            }
            inline int pred(int x) {
                    int ans;
                    Insert(x);
                    ans = Tree[query_max(Tree[root].son[0])].val;
                    erase(x);
                    return ans;
            }
            inline int succ(int x) {
                    int ans;
                    Insert(x);
                    ans = Tree[query_min(Tree[root].son[1])].val;
                    erase(x);
                    return ans;
            }
    } T;
    
    int main() {
            read(N);
            while (N--) {
                    read(opt); read(x);
                    if (opt == 1) T.Insert(x);
                    else if (opt == 2) T.erase(x);
                    else if (opt == 3) writeln(T.query_rank(x));
                    else if (opt == 4) writeln(T.rank(x));
                    else if (opt == 5) writeln(T.pred(x));
                    else if (opt == 6) writeln(T.succ(x));    
            }
            
            return 0;
        
    }
  • 相关阅读:
    隐马尔科夫模型
    计算复杂性理论——函数
    STM32硬件I2C调试
    FPGA简单图像处理
    STM32配置使用外部12MHz晶振
    STM32从模式接受数据
    STM32 I2C读写EEPROM(中断模式)
    STM32 I2C读写EEPROM(POLLING模式)
    STM32串口实验
    STM32使用TIM闪烁LED——PWM方式
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196416.html
Copyright © 2011-2022 走看看