洛谷P3369 普通平衡树

平衡树板子

因为之前写spaly删除出了大锅。。所以就去学了一手fhq-treap。。。
下面是抄来的板子(真香

#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;
}

// fhq-treap
const int N = 100005;
int tree[N][2], val[N], size[N], rnd[N], tot;
int p, q, t, root;

void push_up(int x){
    size[x] = size[tree[x][0]] + size[tree[x][1]] + 1;
}

int merge(int x, int y){
    if(!x || !y) return x + y;
    if(rnd[x] < rnd[y]){
        tree[x][1] = merge(tree[x][1], y);
        push_up(x);
        return x;
    }
    else{
        tree[y][0] = merge(x, tree[y][0]);
        push_up(y);
        return y;
    }
}

void split(int cur, int k, int &x, int &y){
    if(!cur){ x = 0, y = 0; return; }
    if(val[cur] <= k) x = cur, split(tree[cur][1], k, tree[cur][1], y);
    else y = cur, split(tree[cur][0], k, x, tree[cur][0]);
    push_up(cur);
}

int rndom(){
    return rand() << 15 | rand();
}

int newNode(int v){
    size[++tot] = 1, rnd[tot] = rndom(), val[tot] = v;
    return tot;
}

void insert(int x){
    split(root, x, p, q);
    root = merge(merge(p, newNode(x)), q);
}

void del(int x){
    split(root, x, p, t);
    split(p, x - 1, p, q);
    q = merge(tree[q][0], tree[q][1]);
    root = merge(merge(p, q), t);
}

int select(int cur, int k){
    while(1){
        if(size[tree[cur][0]] >= k) cur = tree[cur][0];
        else{
            if(size[tree[cur][0]] + 1 == k) return cur;
            else k = k - size[tree[cur][0]] - 1, cur = tree[cur][1];
        }
    }
}

int ranks(int x){
    int ret = 0; split(root, x - 1, p, q);
    ret = size[p] + 1;
    merge(p, q);
    return ret;
}

int successor(int x){
    int ret = 0; split(root, x, p, q);
    ret = val[select(q, 1)];
    root = merge(p, q);
    return ret;
}

int precursor(int x){
    int ret = 0; split(root, x - 1, p, q);
    ret = val[select(p, size[p])];
    root = merge(p, q);
    return ret;
}

int main(){

    srand(time(0));
    int n = read();
    while(n --){
        int opt = read();
        if(opt == 1) insert(read());
        else if(opt == 2) del(read());
        else if(opt == 3) printf("%d\n", ranks(read()));
        else if(opt == 4) printf("%d\n", val[select(root, read())]);
        else if(opt == 5) printf("%d\n", precursor(read()));
        else printf("%d\n", successor(read()));
    }
    return 0;
}
posted @ 2019-03-28 14:29  清楚少女ひなこ  阅读(170)  评论(0编辑  收藏  举报