Splay Tree(模版)

#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <stdio.h>
#include <deque>

using namespace std;

#define LL long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define inf 1000000000000000000
#define maxn 1000005
#define eps 0.00000001
#define PI acos(-1.0)
#define M 1000000007

int ch[maxn][2], f[maxn], key[maxn], cnt[maxn], size[maxn], pri[maxn * 10];
int sz, root;

inline void newNode(int x, int fa) {
    sz ++;
    ch[sz][0] = ch[sz][1] = 0;
    key[sz] = x; size[sz] = 1;
    cnt[sz] = 1; f[sz] = fa;
}

inline void clear(int x) {
    ch[x][0] = ch[x][1] = f[x] = cnt[x] = key[x] = size[x] = 0;
}

inline int get(int x) {
    return ch[f[x]][1] == x;
}

inline void updata(int x) {
    if(x) {
        size[x] = cnt[x];
        if(ch[x][0]) size[x] += size[ch[x][0]];
        if(ch[x][1]) size[x] += size[ch[x][1]];
    }
}

inline void rotate(int x) {
    int old = f[x], oldf = f[old], which = get(x);
    ch[old][which] = ch[x][which ^ 1];
    f[ch[old][which]] = old;
    f[old] = x; ch[x][which ^ 1] = old; f[x] = oldf;
    if(oldf) ch[oldf][ch[oldf][1] == old] = x;
    updata(old); updata(x);
}

inline void splay(int x) {
    for (int fa; (fa = f[x]); rotate(x))
        if(f[fa])
            rotate((get(x) == get(fa) ? fa : x));
    root = x;
}

inline void insert(int v) {
    if(root == 0) {
        newNode(v, 0);
        root = sz;
        return ;
    }
    int now = root, fa = 0;
    while(1) {
        if(key[now] == v) {
            cnt[now] ++;
            updata(now); updata(fa); splay(now);
            break;
        }
        fa = now;
        now = ch[now][key[now] < v];
        if(now == 0) {
            newNode(v, fa);
            ch[fa][key[fa] < v] = sz;
            updata(fa); splay(sz);
            break;
        }
    }
}

inline int find(int v) {
    int ans = 0, now = root;
    while(1) {
        if(v < key[now])
            now = ch[now][0];
        else {
            ans += (ch[now][0] ? size[ch[now][0]] : 0);
            if(v == key[now]) {
                splay(now);
                return ans + 1;
            }
            ans += cnt[now];
            now = ch[now][1];
        }
    }
}

inline int findx(int x) {
    int now = root;
    while(1) {
        if(ch[now][0] && x <= size[ch[now][0]])
            now = ch[now][0];
        else {
            int temp = (ch[now][0] ? size[ch[now][0]] : 0) + cnt[now];
            if(x <= temp) return key[now];
            x -= temp;
            now = ch[now][1];
        }
    }
}

inline int pre() {
    int now = ch[root][0];
    while(ch[now][1]) now = ch[now][1];
    return now;
}

inline int next() {
    int now = ch[root][1];
    while(ch[now][0]) now = ch[now][0];
    return now;
}

inline void del(int x) {
    int whatever = find(x);
    if(cnt[root] > 1) {
        cnt[root] --;
        return ;
    }
    if(!ch[root][0] && !ch[root][1]) {
        clear(root); root = 0;
        return ;
    }
    if(!ch[root][0]) {
        int oldroot = root;
        root = ch[root][1]; f[root] = 0;
        clear(oldroot);
        return ;
    } else if(!ch[root][1]) {
        int oldroot = root;
        root = ch[root][0]; f[root] = 0;
        clear(oldroot);
        return ;
    }
    int leftbig = pre(), oldroot = root;
    splay(leftbig);
    f[ch[oldroot][1]] = root;
    ch[root][1] = ch[oldroot][1];
    clear(oldroot); updata(root);
    return ;
}

int main(int argc, const char * argv[]) {

    
    return 0;
}



感觉上一个板子有点问题,再加一个模版

#include <stdio.h>
#define maxn 200005
struct SplayTree {
    // Root:Splay Tree根节点
    int Root, Tot;
    // Son[i][0]:i节点的左孩子,Son[i][0]:i节点的右孩子
    int Son[maxn][2];
    // Pre[i]:i节点的父节点
    int Pre[maxn];
    // Val[i]:i节点的权值
    int Val[maxn];
    // Size[i]:以i节点为根的Splay Tree的节点数(包含自身)
    int Size[maxn];
    // Cnt[i]:节点i的权值的出现次数
    int Cnt[maxn];
    
    void PushUp(int X) {
        Size[X] = Size[Son[X][0]] + Size[Son[X][1]] + Cnt[X];
    }
    
    // 判断X节点是其父节点的左孩子还是右孩子
    bool Self(int X) {
        return X == Son[Pre[X]][1];
    }
    
    void Clear(int X) {
        Son[X][0] = Son[X][1] = Pre[X] = Val[X] = Size[X] = Cnt[X] = 0;
    }
    
    // 旋转
    void Rotate(int X) {
        int Fa = Pre[X], FaFa = Pre[Fa], XJ = Self(X);
        Son[Fa][XJ] = Son[X][XJ ^ 1];
        Pre[Son[Fa][XJ]] = Pre[X];
        Son[X][XJ ^ 1] = Pre[X];
        Pre[Fa] = X;
        Pre[X] = FaFa;
        if (FaFa)
            Son[FaFa][Fa == Son[FaFa][1]] = X;
        PushUp(Fa); PushUp(X);
    }
    
    // 旋转X节点到根节点
    void Splay(int X) {
        for (int i = Pre[X]; i = Pre[X]; Rotate(X))
            if (Pre[i])
                Rotate(Self(X) == Self(i) ? i : X);
        Root = X;
    }
    
    // 插入数X
    void Insert(int X) {
        if (!Root) {
            Val[++Tot] = X;
            Cnt[Tot]++;
            Root = Tot;
            PushUp(Root);
            return;
        }
        int Cur = Root, F = 0;
        while (true) {
            if (Val[Cur] == X) {
                Cnt[Cur]++;
                PushUp(Cur);
                PushUp(F);
                Splay(Cur);
                break;
            }
            F = Cur;
            Cur = Son[Cur][Val[Cur] < X];
            if (!Cur) {
                Val[++Tot] = X;
                Cnt[Tot]++;
                Pre[Tot] = F;
                Son[F][Val[F] < X] = Tot;
                PushUp(Tot);
                PushUp(F);
                Splay(Tot);
                break;
            }
        }
    }
    
    // 查询X的排名
    int Rank(int X) {
        int Ans = 0, Cur = Root;
        while (true) {
            if (X < Val[Cur]) {
                Cur = Son[Cur][0];
            }
            else {
                Ans += Size[Son[Cur][0]];
                if (X == Val[Cur]) {
                    Splay(Cur);
                    return Ans + 1;
                }
                Ans += Cnt[Cur];
                Cur = Son[Cur][1];
            }
        }
    }
    
    // 查询排名为X的数
    int Kth(int X) {
        int Cur = Root;
        while (true) {
            if (Son[Cur][0] && X <= Size[Son[Cur][0]]) {
                Cur = Son[Cur][0];
            }
            else {
                X -= Cnt[Cur] + Size[Son[Cur][0]];
                if (X <= 0) {
                    return Val[Cur];
                }
                Cur = Son[Cur][1];
            }
        }
    }
    
    /*
     * 在Insert操作时X已经Splay到根了
     * 所以X的前驱就是X的左子树的最右边的节点
     * 后继就是X的右子树的最左边的节点
     */
    
    // 求前驱
    int Path() {
        int Cur = Son[Root][0];
        while (Son[Cur][1]) {
            Cur = Son[Cur][1];
        }
        return Cur;
    }
    
    // 求后继
    int Next() {
        int Cur = Son[Root][1];
        while (Son[Cur][0]) {
            Cur = Son[Cur][0];
        }
        return Cur;
    }
    
    // 删除节点X
    void Delete(int X) {
        // 将X旋转到根
        Rank(X);
        if (Cnt[Root] > 1) {
            Cnt[Root]--;
            PushUp(Root);
            return;
        }
        if (!Son[Root][0] && !Son[Root][1]) {
            Clear(Root);
            Root = 0;
            return;
        }
        if (!Son[Root][0]) {
            int Temp = Root;
            Root = Son[Root][1];
            Pre[Root] = 0;
            Clear(Temp);
            return;
        }
        if (!Son[Root][1]) {
            int Temp = Root;
            Root = Son[Root][0];
            Pre[Root] = 0;
            Clear(Temp);
            return;
        }
        int Temp = Path(), Old = Root;
        Splay(Temp);
        Pre[Son[Old][1]] = Temp;
        Son[Temp][1] = Son[Old][1];
        Clear(Old);
        PushUp(Root);
    }
    
    void Print(int r, int d) {
        if(Son[r][0])
            Print(Son[r][0], d);
        printf("%d ", Val[r]);
        if(Son[r][1])
            Print(Son[r][1], d);
    }
};
int main(){
    SplayTree a;
    a.Insert(1);
    a.Insert(2);
    a.Insert(5);
    a.Splay(1);
    a.Print(a.Root, 1);
    
}

再存一个板子

#include <iostream>
#include <string.h>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <stdio.h>
#include <deque>

using namespace std;

#define LL long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define inf 1000000000000000000
#define maxn 200005
#define eps 0.00000001
#define PI acos(-1.0)
#define M 1000000007

int ch[maxn][2], f[maxn], key[maxn], size[maxn], cnt[maxn];
int rt, tot;

void newNode(int &r, int x, int fa) {
    r = ++ tot;
    ch[r][0] = ch[r][1] = 0;
    key[r] = x; size[r] = 1;
    f[r] = fa; cnt[r] = 1;
}

void rotate(int r, int kind) {
    int y = f[r];
    ch[y][!kind] = ch[r][kind];
    f[ch[r][kind]] = y;
    if(f[y])
        ch[f[y]][ch[f[y]][1] == y] = r;
    f[r] = f[y];
    ch[r][kind] = y;
    f[y] = r;
    size[r] = size[y];
    size[y] = cnt[y] + size[ch[y][0]] + size[ch[y][1]];
}

void splay(int r, int goal) {
    while(f[r] != goal) {
        if(f[f[r]] == goal)
            rotate(r, ch[f[r]][0] == r);
        else {
            int y = f[r];
            int kind = ch[f[y]][0] == y;
            if(ch[f[r]][kind] == r) {
                rotate(r, !kind);
                rotate(r, kind);
            }else {
                rotate(y, kind);
                rotate(r, kind);
            }
        }
    }
    if(goal == 0) rt = r;
}

void findx(int x) {
    int r = rt;
    while(size[ch[r][0]] + cnt[r] != x) {
        if(size[ch[r][0]] + cnt[r] < x) {
            x -= size[ch[r][0]] + cnt[r];
            r = ch[r][1];
        }else
            r = ch[r][0];
    }
    splay(r, 0);
}

void insert(int p, int v) {
    if(p == 0) {
        int r = rt;
        size[r] ++;
        while (ch[r][0]) {
            r = ch[r][0];
            size[r] ++;
        }
        newNode(ch[r][0], v, r);
        splay(ch[r][0], 0);
        return ;
    }
    findx(p);
    int r = rt;
    newNode(rt, v, 0);
    ch[rt][1] = ch[r][1];
    f[ch[r][1]] = rt;
    ch[r][1] = 0;
    size[r] -= size[ch[rt][1]];
    ch[rt][0] = r;
    f[r] = rt;
    size[rt] = 1 + size[ch[rt][1]] + size[ch[rt][0]];
}

void remove() {
    if(!rt) return ;
    int y;
    if(ch[rt][1] == 0)
        rt = ch[rt][0];
    else {
        y = ch[rt][1];
        while(ch[y][0])
            y = ch[y][0];
        splay(y, rt);
        ch[y][0] = ch[rt][0];
        f[ch[rt][0]] = y;
        rt = y;
    }
    f[rt] = 0;
}

void Print(int r, int& d) {
    if(ch[r][0])
        Print(ch[r][0], d);
    printf("%d%s", key[r], d == tot ? "\n" : " ");
    d ++;
    if(ch[r][1])
        Print(ch[r][1], d);
}

int main(int argc, const char * argv[]) {
    int n, p, v, vis;
    while (scanf("%d", &n) != EOF) {
        tot = rt = 0;
        while(n --) {
            scanf("%d", &vis);
            if(vis) {
                scanf("%d %d", &p, &v);
                if(rt == 0)
                    newNode(rt, v, 0);
                else
                    insert(p, v);
            }
            else {
                scanf("%d", &p);
                findx(p);
                remove();
            }
            int d = 1;
            Print(rt, d);
        }

    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/82970828