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;
    }
    
  • 相关阅读:
    dotnet core 获取 MacAddress 地址方法
    dotnet core 获取 MacAddress 地址方法
    dotnet core 发布只带必要的依赖文件
    dotnet core 发布只带必要的依赖文件
    Developing Universal Windows Apps 开发UWA应用 问答
    Developing Universal Windows Apps 开发UWA应用 问答
    cmd 如何跨驱动器移动文件夹
    cmd 如何跨驱动器移动文件夹
    C++ 驱动开发 error LNK2019
    C++ 驱动开发 error LNK2019
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10764630.html
Copyright © 2011-2022 走看看