splay

Posted junk-yao-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了splay相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
inline int qread(){
    register int x = 0, ch = getchar(), flag = 0;
    while(!isdigit(ch))    flag = ch == -, ch = getchar();
    while(isdigit(ch))    x = (x << 3) + (x << 1) + ch - 48, ch = getchar();
    return flag ? -x : x;
}
int n, m;
int f[maxn], ch[maxn][2], size[maxn], rev[maxn], rt;
inline void pushup(int x) {
    size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
}
void pushdown(int x) {
    if(rev[x]) {
        swap(ch[x][0], ch[x][1]);
        rev[ch[x][0]] ^= 1;
        rev[ch[x][1]] ^= 1;
        rev[x] = 0;
    }
}
void rotate(int x, int &k) {
    int y = f[x], z = f[y], kind;
    if(ch[y][1] == x) kind = 1;    else kind = 0;
    if(y == k)    k = x;
    else{if(ch[z][0] == y) ch[z][0] = x;    else ch[z][1] = x;}
    ch[y][kind] = ch[x][kind ^ 1], f[ch[y][kind]] = y;
    ch[x][kind ^ 1] = y, f[y] = x, f[x] = z;
    pushup(x), pushup(y);
}
void splay(int x, int &k) {
    while(x != k) {
        int y = f[x], z = f[y];
        if(y != k) {
            if((ch[y][0] == x) ^ (ch[z][0] == y))    rotate(x, k);
            else rotate(y, k);
        }
        rotate(x, k);
    }
}
void build(int l, int r, int from) {
    if(l > r)    return ;
    int mid = (l + r) >> 1;
    if(mid < from)    ch[from][0] = mid;    else ch[from][1] = mid;
    f[mid] = from;    size[mid] = 1;
    if(l == r)    return ;
    build(l, mid - 1, mid);
    build(mid + 1, r, mid);
    pushup(mid);
}
int find(int x, int k) {
    pushdown(x);
    int s = size[ch[x][0]];
    if(k == s + 1)    return x;
    if(k <= s)    return find(ch[x][0], k);
    else        return find(ch[x][1], k - s - 1);
}
void rever(int l, int r) {
    int x = find(rt, l), y = find(rt, r + 2);
    splay(x, rt);
    splay(y, ch[x][1]);
    int z = ch[y][0];
    rev[z] ^= 1;
}
void show(int x){
    if(x){
        cout << x << " " << f[x] << " " << ch[x][0] << " " << ch[x][1] << endl;     
        show(ch[x][0]);
        show(ch[x][1]);
    }
}
int main() {
    scanf("%d%d", &n, &m);
    rt = (n + 3) >> 1;
    build(1, n + 2, rt);
    for(int i = 1; i <= m; i++) {
        int L, R;
        scanf("%d%d", &L, &R);
        rever(L, R);
    }
    for(int i = 2; i <= n + 1; i++)    printf("%d ", find(rt, i) - 1);
    return 0;
}

 

以上是关于splay的主要内容,如果未能解决你的问题,请参考以下文章

UESTC2021暑假前集训(splay树)

SPLAY or SPALY ?

模板Splay

文艺平衡树(splay模板)

bzoj2733 永无乡 splay树的启发式合并

●Splay的一些题