平衡树(fhq无旋treap)

fhq板子(代码正确且风格易懂)

洛谷P3369

#include
#include
#include
#include
#include
using namespace std;
const int N = 105000;
int val[N], son[N][2];
int rnd[N], tot, n;
int siz[N], root, a, p, x, y, z;
inline void update(int x) {
    siz[x] = siz[son[x][1]] + siz[son[x][0]] + 1;
}
inline int build(int x) {
    siz[++tot] = 1, rnd[tot] = rand();
    val[tot] = x; return tot;
}
int merge(int x,int y) {
    if (!x || !y) return x + y;
    if (rnd[x] < rnd[y]) {
        son[x][1] = merge(son[x][1], y);
        update(x); return x;
    }
    son[y][0] = merge(x, son[y][0]);
    update(y); return y;
}
void split(int now,int k,int &x,int &y) {
    if (!now) x = y = 0;
    else {
        if (val[now] <= k) x = now, split(son[x][1], k, son[x][1], y);
        else y = now, split(son[y][0], k, x, son[y][0]);
        update(now);
    }
}

inline int kth(int now, int k) {
    while (1) {
        if (k <= siz[son[now][0]]) now = son[now][0];
        else if (k == siz[son[now][0]] + 1) return now;
        else k -= siz[son[now][0]] + 1, now = son[now][1];
    }
}
template  
void read(T &x) {
    x = 0; int f = 1;char c = getchar();
    while (!isdigit(c)) { if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) { x = (x << 3)+(x << 1) + c-'0'; c = getchar();}
    x *= f;
}   
int main() {
    srand(time(0));
    read(n);
    for (int i = 1;i <= n; i++) {
        read(p), read(a);
        if (p == 1) {
            split(root, a, x, y);
            root = merge(merge(x, build(a)), y);
        }
        else if (p == 2) {
            split(root, a, x, y);
            split(x, a-1, x, z);
            z = merge(son[z][0], son[z][1]);
            root = merge(merge(x, z), y);
        }
        else if (p == 3) {
            split(root, a-1, x, y);
            printf ("%d\n", siz[x] + 1);
            root = merge(x, y);
        }
        else if (p == 4) printf ("%d\n", val[kth(root, a)]);
        else if (p == 5) {
            split(root, a-1, x, y);
            printf ("%d\n", val[kth(x, siz[x])]);
            root = merge(x, y);
        }
        else {
            split(root, a, x, y);
            printf ("%d\n", val[kth(y, 1)]);
            root = merge(x, y);
        }
    }
    return 0;
}

洛谷P3391

#include
#include
#include
#include
#include
using namespace std;
const int N = 100050;
int rnd[N], siz[N];
int cnt, n, l, r;
int tag[N], son[N][2];
int val[N], root, x, y, z;
inline int build(int x) {
    siz[++cnt] = 1, val[cnt] = x;
    rnd[cnt] = rand(); return cnt;
}
inline void update(int x) {
    siz[x] = siz[son[x][1]] + siz[son[x][0]] + 1;
}
void spread(int x) {
    if (tag[x]) {
        swap(son[x][0], son[x][1]);
        if (son[x][0]) tag[son[x][0]] ^= 1;
        if (son[x][1]) tag[son[x][1]] ^= 1;
        tag[x] = 0;
    }
}
void split(int now,int k,int &x,int &y) {
    if (!now) x = y = 0;
    else {
        spread(now);
        if (siz[son[now][0]] < k) x = now, split(son[x][1], k - siz[son[now][0]] - 1, son[x][1], y);
        else y = now, split(son[y][0], k, x, son[y][0]);
        update(now);
    }
}
int merge(int x,int y) {
    if(!x || !y) return x + y;
    if (rnd[x] < rnd[y]) {
        spread(x);
        son[x][1] = merge(son[x][1], y);
        update(x); return x;
    }
    spread(y);
    son[y][0] = merge(x, son[y][0]);
    update(y); return y;
}
template  
void read(T &x) {
    x = 0; int f = 1;char c = getchar();
    while (!isdigit(c)) { if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) { x = (x << 3)+(x << 1) + c-'0'; c = getchar();}
    x *= f;
}   
int m;
void res(int x) {
    if (!x) return;
    spread(x);
    res(son[x][0]);
    printf ("%d ", val[x]);
    res(son[x][1]);
}
int main() {
    read(n), read(m);
    for (int i = 1;i <= n; i++) root = merge(root, build(i));
    while (m--) {
        read(l), read(r);
        split(root, l - 1, x, y);
        split(y, r - l+ 1, y, z);
        tag[y] ^= 1;
        root = merge(merge(x, y), z);
    }
    res(root);
    return 0;
}

可持久化平衡树
p3835

#include
#include
#include
#include
#include
using namespace std;
const int N = 500500 * 50;
const int INF = 2147483647;
int T[N], val[N], rnd[N];
int siz[N], son[N][2];
int cnt; 

template  
void read(T &x) {
    x = 0; int f = 1;char c = getchar();
    while (!isdigit(c)) { if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) { x = (x << 3)+(x << 1) + c-'0'; c = getchar();}
    x *= f;
}

inline void update(int x) {
    siz[x] = siz[son[x][0]] + siz[son[x][1]] + 1;
}

inline void cpy(int x,int y) {
    siz[x] = siz[y], son[x][1] = son[y][1];
    son[x][0] = son[y][0];
    val[x] = val[y], rnd[x] = rnd[y];
}
inline int build(int x) {
    val[++cnt] = x, siz[cnt] = 1;
    rnd[cnt] = rand(); return cnt;
}
    
void split(int now,int k,int &x,int &y) {
    if (!now) x = y = 0;
    else {
        if (val[now] <= k) {
            x = ++cnt, cpy(x, now), split(son[x][1], k, son[x][1], y);
            update(x);
        }
        else {
            y = ++cnt, cpy(y, now), split(son[y][0], k, x, son[y][0]);
            update(y);
        }
    }
}

int merge(int x,int y) {
    if (!x || !y) return x + y;
    if (rnd[x] < rnd[y]) {
        int p = ++cnt; cpy(p, x);
        son[p][1] = merge(son[p][1], y); 
        update(p); return p;
    }
    int p = ++cnt; cpy(p, y);
    son[p][0] = merge(x, son[p][0]); 
    update(p); return p;
} 

int kth(int now,int x) {
    while (1) {
        if (siz[son[now][0]] >= x) now = son[now][0];
        else if (siz[son[now][0]] + 1 == x) return now;
        else x -= siz[son[now][0]] + 1, now = son[now][1];
    }
}

int n, x, y, z;
int op, P, a;
int main() {
    srand(20040202);
    read(n);
    for (int i = 1;i <= n; i++) {
        read(P), read(op), read(a);
        T[i] = T[P];
        if (op == 1) {
            split(T[i], a, x, y);
            T[i] = merge(merge(x, build(a)), y);
        }
        else if (op == 2) {
            split(T[i], a, x, z);
            split(x, a-1, x, y);
            y = merge(son[y][0], son[y][1]);
            T[i] = merge(merge(x, y), z);
        }
        else if (op == 3) {
            split(T[i], a-1, x, y);
            printf ("%d\n", siz[x] + 1);
            T[i] = merge(x, y);
        }
        else if (op == 4) printf ("%d\n", val[kth(T[i], a)]);
        else if (op == 5) {
            split(T[i], a-1, x, y);
            if (siz[x] == 0) printf ("%d\n", -INF);
            else printf ("%d\n", val[kth(x, siz[x])]);
            T[i] = merge(x, y);
        }
        else if (op == 6) {
            split(T[i], a, x, y);
            if (siz[y] == 0) printf ("%d\n", INF);
            else printf ("%d\n", val[kth(y, 1)]);
            T[i] = merge(x, y);
        }
    }
    return 0;
}   

你可能感兴趣的:(平衡树(fhq无旋treap))