zoukankan      html  css  js  c++  java
  • 洛谷P3380 二逼平衡树

    线段树+平衡树

    我!又!被!卡!常!了!

    以前的splay偷懒的删除找前驱后继的办法被卡了QAQ

    放一个在洛谷开O2才能过的代码。。我太菜了。。

    #include <bits/stdc++.h>
    #define INF 2147483647
    #define rint register int
    #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;
    }
    static short c[20], top;
    inline void print(int x){
        if(!x){ putchar(48); putchar('
    '); return;}
        if(x < 0) putchar('-'),x *= -1;
        for(top = 0; x ; c[++top] = x % 10, x /= 10);
        for(; top; putchar(c[top--]^48));
        putchar('
    ');
    }
    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 = 3000005;
    int n, m, tot, tmp, root[N], val[N], size[N], fa[N], ch[N][2], cnt[N], a[N];
    
    inline int init(rint v, rint f){
        ++tot;
        val[tot] = v, fa[tot] = f,  size[tot] = cnt[tot] = 1;
        ch[tot][0] = ch[tot][1] = 0;
        return tot;
    }
    
    inline void push_up(rint x){
        size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x];
    }
    
    inline void rotate(rint 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);
    }
    
    inline void splay(rint i, rint x, rint 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[i] = x;
    }
    
    inline void insert(rint i, rint x){
        if(!root[i]){
            root[i] = init(x, 0);
            return;
        }
        rint cur = root[i];
        while(ch[cur][x > val[cur]]){
            if(x == val[cur]) break;
            cur = ch[cur][x > val[cur]];
        }
        if(x == val[cur]) cnt[cur] ++, splay(i, cur, 0);
        else ch[cur][x > val[cur]] = init(x, cur), splay(i, ch[cur][x > val[cur]], 0);
    }
    
    inline void find(rint i, rint x){
        if(!root[i]) return;
        rint cur = root[i];
        while(x != val[cur] && ch[cur][x > val[cur]])
            cur = ch[cur][x > val[cur]];
        splay(i, cur, 0);
    }
    
    /*inline int precursor(rint i, rint x){
        find(i, x);
        if(val[root[i]] < x) return root[i];
        rint cur = ch[root[i]][0];
        while(ch[cur][1]) cur = ch[cur][1];
        return cur;
    }
    
    inline int successor(rint i, rint x){
        find(i, x);
        if(val[root[i]] > x) return root[i];
        rint cur = ch[root[i]][1];
        while(ch[cur][0]) cur = ch[cur][0];
        return cur;
    }*/
    
    inline int precursor(int i, int v){
        int x = root[i], ans = -INF;
        while (x){
            if (val[x] < v){
                if (ans < val[x]) ans = val[x];
                x = ch[x][1];
            }
            else x = ch[x][0];
        }
        return ans;
    }
    
    inline int successor(int i, int v){
        int x = root[i], ans = INF;
        while (x){
            if (val[x] > v){
                if (ans > val[x]) ans = val[x];
                x = ch[x][0];
            }
            else x = ch[x][1];
        } return ans;
    }
    
    
    inline void remove(rint i, rint x){
        rint pre = precursor(i, x), suc = successor(i, x);
        splay(i, pre, 0), splay(i, suc, root[i]);
        rint key = ch[suc][0];
        if(cnt[key] > 1) cnt[key] --, splay(i, key, 0);
        else ch[suc][0] = 0;
        push_up(suc);
    }
    
    inline void clear(int x){
        fa[x] = ch[x][0] = ch[x][1] = size[x] = cnt[x] = val[x] = 0;
    }
    
    inline void del(rint i, rint x){
        find(i, x);
        int cur = root[i];
        if(cnt[cur] > 1){
            cnt[cur] --;
            return;
        }
        if(!ch[cur][0]){
            int y = ch[cur][1];
            root[i] = y, fa[y] = 0;
            return;
        }
        if(!ch[cur][1]){
            int y = ch[cur][0];
            root[i] = y, fa[y] = 0;
            return;
        }
        int p = ch[cur][0];
        while(ch[p][1]) p = ch[p][1];
        int oldrt = root[i];
        splay(i, p, 0);
        ch[root[i]][1] = ch[oldrt][1];
        fa[ch[oldrt][1]] = root[i];
        clear(oldrt);
        push_up(root[i]);
        return;
    }
    
    void buildTree(rint rt, rint l, rint r){
        insert(rt, INF), insert(rt, -INF);
        if(l == r) return;
        rint mid = (l + r) >> 1;
        buildTree(rt << 1, l, mid);
        buildTree(rt << 1 | 1, mid + 1, r);
        push_up(rt);
    }
    
    void segInsert(rint rt, rint l, rint r, rint k, rint x){
        insert(rt, x);
        if(l == r) return;
        rint mid = (l + r) >> 1;
        if(k <= mid) segInsert(rt << 1, l, mid, k, x);
        else segInsert(rt << 1 | 1, mid + 1, r, k, x);
    }
    
    int segRank(rint rt, rint l, rint r, rint x, rint ql, rint qr){
        if(l == ql && r == qr){
            find(rt, x);
            if(val[root[rt]] >= x) return size[ch[root[rt]][0]] - 1;
            return size[ch[root[rt]][0]] + cnt[root[rt]] - 1;
        }
        rint mid = (l + r) >> 1;
        if(qr <= mid) return segRank(rt << 1, l, mid, x, ql, qr);
        else if(ql > mid) return segRank(rt << 1 | 1, mid + 1, r, x, ql, qr);
        return segRank(rt << 1, l, mid, x, ql, mid) + segRank(rt << 1 | 1, mid + 1, r, x, mid + 1, qr);
    }
    
    void segModify(rint rt, rint l, rint r, rint pos, rint k){
        insert(rt, k), del(rt, a[pos]);
        if(l == r) return;
        rint mid = (l +r) >> 1;
        if(pos <= mid) segModify(rt << 1, l, mid, pos, k);
        else segModify(rt << 1 | 1, mid + 1, r, pos, k);
    }
    
    int segPrecursor(rint rt, rint l, rint r, rint x, rint ql, rint qr){
        if(l == ql && r == qr){
            return precursor(rt, x);
        }
        rint mid = (l + r) >> 1;
        if(qr <= mid) return segPrecursor(rt << 1, l, mid, x, ql, qr);
        else if(ql > mid) return segPrecursor(rt << 1 | 1, mid + 1, r, x, ql, qr);
        return max(segPrecursor(rt << 1, l, mid, x, ql, mid), segPrecursor(rt << 1 | 1, mid + 1, r, x, mid + 1, qr));
    }
    
    int segSuccessor(rint rt, rint l, rint r, rint x, rint ql, rint qr){
        if(l == ql && r == qr){
            return successor(rt, x);
        }
        rint mid = (l + r) >> 1;
        if(qr <= mid) return segSuccessor(rt << 1, l, mid, x, ql, qr);
        else if(ql > mid) return segSuccessor(rt << 1 | 1, mid + 1, r, x, ql, qr);
        return min(segSuccessor(rt << 1, l, mid, x, ql, mid), segSuccessor(rt << 1 | 1, mid + 1, r, x, mid + 1, qr));
    }
    
    inline int select(rint l, rint r, rint k){
        rint ll = 0, rr = tmp;
        while(ll < rr){
            rint mid = (ll + rr + 1) >> 1;
            if(segRank(1, 1, n, mid, l, r) + 1 > k) rr = mid - 1;
            else ll = mid;
        }
        return ll;
    }
    
    int main(){
    
        //freopen("data.txt","r",stdin);
    
        //clock_t startTime = clock();
    
        n = read(), m = read();
        tmp = -INF;
        buildTree(1, 1, n);
        for(rint i = 1; i <= n; i ++) a[i] = read(), tmp = max(tmp, a[i]), segInsert(1, 1, n, i, a[i]);
        while(m --){
            rint opt = read();
            if(opt == 1){
                rint l = read(), r = read(), k = read();
                print(segRank(1, 1, n, k, l, r) + 1);
                //printf("%d
    ", segRank(1, 1, n, k, l, r) + 1);
            }
            else if(opt == 2){
                rint l = read(), r = read(), k = read();
                print(select(l, r, k));
                //printf("%d
    ", select(l, r, k));
            }
            else if(opt == 3){
                rint pos = read(), k = read();
                segModify(1, 1, n, pos, k);
                a[pos] = k;
            }
            else if(opt == 4){
                rint l = read(), r = read(), k = read();
                print(segPrecursor(1, 1, n, k, l, r));
                //printf("%d
    ", segPrecursor(1, 1, n, k, l, r));
            }
            else if(opt == 5){
                rint l = read(), r = read(), k = read();
                print(segSuccessor(1, 1, n, k, l, r));
                //printf("%d
    ", segSuccessor(1, 1, n, k, l, r));
            }
        }
    
        //clock_t endTime = clock();
    
        //cout << "time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
    
        return 0;
    }
    
  • 相关阅读:
    OpenST Basic tool library
    本地自旋锁与信号量/多服务台自旋队列-spin wait风格的信号量
    [IOS]mac以太网连接
    Android自己定义控件皮肤
    DirectX11 学习笔记1
    启用QNX系统,海尔智能冰箱或成业界“宝马”
    vu 是什么
    java.lang.NoClassDefFoundError: Lorg/apache/log4j/Logger报错
    关于Maven项目install时出现No compiler is provided in this environment的处理
    taotao购物车
  • 原文地址:https://www.cnblogs.com/onionQAQ/p/10770566.html
Copyright © 2011-2022 走看看