ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3369 【模板】普通平衡树 splay解法

2022-03-20 08:02:36  阅读:155  来源: 互联网

标签:par ch cur val int splay P3369 root 模板


P3369 【模板】普通平衡树

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int ch[N][2], par[N], val[N], cnt[N], size[N], ncnt, root;
bool chk(int x) {
    return ch[par[x]][1] == x;
}
void pushup(int x) {
    size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x];
}
void rotate(int x) {
    int y = par[x], z = par[y], k = chk(x), w = ch[x][k^1];
    ch[y][k] = w; par[w] = y;
    ch[z][chk(y)] = x; par[x] = z;
    ch[x][k^1] = y; par[y] = x;
    pushup(y); pushup(x);
}
void splay(int x, int goal = 0) {
    while (par[x] != goal) {
        int y = par[x], z = par[y];
        if (z != goal) {
            if (chk(x) == chk(y)) rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
    if (!goal) root = x;
}
void insert(int x) {
    int cur = root, p = 0;
    while (cur && val[cur] != x) {
        p = cur;
        cur = ch[cur][x > val[cur]];
    }
    if (cur) {
        cnt[cur]++;
    } else {
        cur = ++ncnt;
        if (p) ch[p][x > val[p]] = cur;
        ch[cur][0] = ch[cur][1] = 0;
        par[cur] = p; val[cur] = x;
        cnt[cur] = size[cur] = 1;
    }
    splay(cur);
}
void find(int x) {
    int cur = root;
    while (ch[cur][x > val[cur]] && x != val[cur]) {
        cur = ch[cur][x > val[cur]];
    }
    splay(cur);
}
int kth(int k) {
    int cur = root;
    while (1) {
        if (ch[cur][0] && k <= size[ch[cur][0]]) {
            cur = ch[cur][0];
        } else if (k > size[ch[cur][0]] + cnt[cur]) {
            k -= size[ch[cur][0]] + cnt[cur];
            cur = ch[cur][1];
        } else {
            splay(cur);
            return cur;
        }
    }
}
int pre(int x) {
    find(x);
    if (val[root] < x) return root;
    int cur = ch[root][0];
    while (ch[cur][1]) cur = ch[cur][1];
    splay(cur);
    return cur;
}
int succ(int x) {
    find(x);
    if (val[root] > x) return root;
    int cur = ch[root][1];
    while (ch[cur][0]) cur = ch[cur][0];
    splay(cur);
    return cur;
}
void remove(int x) {
    int last = pre(x), next = succ(x);
    splay(last); splay(next, last);
    int del = ch[next][0];
    if (cnt[del] > 1) {
        cnt[del]--;
        splay(del);
    }
    else ch[next][0] = 0;
    pushup(next), pushup(root);
}
int n, op, x;
int main() {
    scanf("%d", &n);
    insert(0x3f3f3f3f);
    insert(0xcfcfcfcf);
    while (n--) {
        scanf("%d%d", &op, &x);
        switch (op) {
            case 1: insert(x); break;
            case 2: remove(x); break;
            case 3: find(x); printf("%d\n", size[ch[root][0]]); break;
            case 4: printf("%d\n", val[kth(x+1)]); break;
            case 5: printf("%d\n", val[pre(x)]); break;
            case 6: printf("%d\n", val[succ(x)]); break;
        }
    }
}

  

标签:par,ch,cur,val,int,splay,P3369,root,模板
来源: https://www.cnblogs.com/smghj/p/16028909.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有