zoukankan      html  css  js  c++  java
  • BZOJ 1861 书架

    平衡树

    随便一个splay搞搞就行啦~~

    需要一个pos数组来查找书编号为i的节点号

    #include <bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define full(a, b) memset(a, b, sizeof a)
    using namespace std;
    typedef long long ll;
    inline int lowbit(int x){ return x & (-x); }
    inline int read(){
        int X = 0, w = 0; char ch = 0;
        while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
        while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
        return w ? -X : X;
    }
    inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
    inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
    template<typename T>
    inline T max(T x, T y, T z){ return max(max(x, y), z); }
    template<typename T>
    inline T min(T x, T y, T z){ return min(min(x, y), z); }
    template<typename A, typename B, typename C>
    inline A fpow(A x, B p, C lyd){
        A ans = 1;
        for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
        return ans;
    }
    const int N = 80005;
    int n, m, tot, root, ch[N][2], fa[N], pos[N], size[N], val[N], a[N];
    
    int init(int v, int f){
        ++tot;
        val[tot] = v, size[tot] = 1, pos[v] = tot, fa[tot] = f;
        ch[tot][0] = ch[tot][1] = 0;
        return tot;
    }
    
    void push_up(int x){
        int l = ch[x][0], r = ch[x][1];
        size[x] = size[l] + size[r] + 1;
        pos[val[x]] = x;
    }
    
    void rotate(int x){
        int y = fa[x], z = fa[y], p = (ch[y][1] == x) ^ 1;
        ch[y][p^1] = ch[x][p], fa[ch[x][p]] = y;
        ch[z][ch[z][1] == y] = x, fa[x] = z;
        ch[x][p] = y, fa[y] = x;
        push_up(y), push_up(x);
    }
    
    void splay(int x, int goal){
        if(x == goal) return;
        while(fa[x] != goal){
            int y = fa[x], z = fa[y];
            if(z != goal){
                (ch[y][0] == x) ^ (ch[z][0] == y) ? rotate(x) : rotate(y);
            }
            rotate(x);
        }
        push_up(x);
        if(goal == 0) root = x;
    }
    
    void top(int x){
        splay(pos[x], 0);
        if(!ch[root][0]) return;
        if(!ch[root][1]){
            ch[root][1] = ch[root][0], ch[root][0] = 0;
            return;
        }
        int cur = ch[root][1];
        while(ch[cur][0]) cur = ch[cur][0];
        ch[cur][0] = ch[root][0], fa[ch[root][0]] = cur;
        ch[root][0] = 0;
        splay(ch[cur][0], 0);
    }
    
    void bottom(int x){
        splay(pos[x], 0);
        if(!ch[root][1]) return;
        if(!ch[root][0]){
            ch[root][0] = ch[root][1], ch[root][1] = 0;
            return;
        }
        else{
            int cur = ch[root][0];
            while(ch[cur][1]) cur = ch[cur][1];
            ch[cur][1] = ch[root][1], fa[ch[root][1]] = cur;
            ch[root][1] = 0;
            splay(ch[cur][1], 0);
        }
    }
    
    void insert(int x, int t){
        splay(pos[x], 0);
        if(!t) return;
        int p = t == 1 ? 1 : 0;
        int cur = ch[root][p];
        while(ch[cur][p^1]) cur = ch[cur][p^1];
        int tmp = pos[x], to = val[cur];
        swap(val[tmp], val[cur]);
        swap(pos[x], pos[to]);
        splay(ch[root][p], 0);
    }
    
    int ask(int x){
        splay(pos[x], 0);
        return size[ch[root][0]];
    }
    
    int query(int x){
        int cur = root, p = size[ch[root][0]];
        while(1){
            if(x > p + 1){
                cur = ch[cur][1];
                x -= p + 1;
            }
            else{
                if(p >= x) cur = ch[cur][0];
                else return val[cur];
            }
            p = size[ch[cur][0]];
        }
    }
    
    int buildTree(int x, int l, int r){
        if(l > r) return 0;
        int mid = (l + r) >> 1;
        int p = init(a[mid], x);
        ch[p][0] = buildTree(p, l, mid - 1);
        ch[p][1] = buildTree(p, mid + 1, r);
        push_up(p);
        return p;
    }
    
    int main(){
    
        n = read(), m = read();
        for(int i = 1; i <= n; i ++) a[i] = read();
        root = buildTree(0, 1, n);
        while(m --){
            char opt[20]; scanf("%s", opt);
            int s = read();
            if(opt[0] == 'T') top(s);
            else if(opt[0] == 'B') bottom(s);
            else if(opt[0] == 'I') { int x = read(); insert(s, x); }
            else if(opt[0] == 'A') printf("%d
    ", ask(s));
            else if(opt[0] == 'Q') printf("%d
    ", query(s));
        }
        return 0;
    }
    
  • 相关阅读:
    ubuntu 16.04 连接无线网络
    linux的内存管理-抛砖引玉
    linux的进程调度-抛砖引玉
    AliOS Things 异步事件框架Yloop
    AliOS Things 云端物联网操作系统
    linux performance tools
    linux进程调度
    linux 内核Lockup机制浅析
    cache和内存屏障
    linux设备模型及实例
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10764630.html
Copyright © 2011-2022 走看看