欢迎拜访我的博客大本营。
图片应该显示的出来吧。
P3369 【模板】普通平衡树
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010, INF = 1e9;
struct Node {
int ch[2];
int p, v;
int size;
int cnt;
}tr[N];
int root, idx;
void pushup(int u) {
tr[u].size = tr[tr[u].ch[0]].size + tr[tr[u].ch[1]].size + tr[u].cnt;
}
void rotate(int x) {
int y = tr[x].p;
int z = tr[y].p;
int k = (tr[y].ch[1] == x);
tr[y].ch[k] = tr[x].ch[k ^ 1], tr[tr[x].ch[k ^ 1]].p = y;
tr[x].ch[k ^ 1] = y, tr[y].p = x;
tr[z].ch[tr[z].ch[1] == y] = x, tr[x].p = z;
pushup(y);
pushup(x);
}
void splay(int x, int k) {
while (tr[x].p != k) {
int y = tr[x].p;
int z = tr[y].p;
if (z != k) {
if ((tr[z].ch[1] == y) ^ (tr[y].ch[1] == x)) rotate(x);
else rotate(y);
}
rotate(x);
}
if (!k) root = x;
}
void insert(int x) {
int u = root, p = 0;
while (u && tr[u].v != x) {
p = u;
u = tr[u].ch[x > tr[u].v];
}
if (u) tr[u].cnt++;
else {
u = ++idx;
if (p) tr[p].ch[x > tr[p].v] = u;
tr[u].p = p;
tr[u].v = x;
tr[u].size = 1;
tr[u].cnt = 1;
}
splay(u, 0);
}
void find(int x) {
int u = root;
while (tr[u].ch[x > tr[u].v] && tr[u].v != x) u = tr[u].ch[x > tr[u].v];
splay(u, 0);
}
int get_pre(int x) {
find(x);
if (tr[root].v < x) return root;
int u = tr[root].ch[0];
while (tr[u].ch[1]) u = tr[u].ch[1];
splay(u, 0);
return u;
}
int get_suc(int x) {
find(x);
if (tr[root].v > x) return root;
int u = tr[root].ch[1];
while (tr[u].ch[0]) u = tr[u].ch[0];
splay(u, 0);
return u;
}
void remove(int x) {
int pre = get_pre(x);
int suc = get_suc(x);
splay(pre, 0);
splay(suc, pre);
int del = tr[suc].ch[0];
if (tr[del].cnt > 1) tr[del].cnt--, splay(del, 0);
else tr[suc].ch[0] = 0, splay(suc, 0);
}
int get_rank_by_key(int x) {
insert(x);
int res = tr[tr[root].ch[0]].size;
remove(x);
return res;
}
int get_key_by_rank(int k) {
int u = root;
while (true) {
if (k <= tr[tr[u].ch[0]].size) u = tr[u].ch[0];
else if (k <= tr[tr[u].ch[0]].size + tr[u].cnt) break;
else k -= tr[tr[u].ch[0]].size + tr[u].cnt, u = tr[u].ch[1];
}
splay(u, 0);
return tr[u].v;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
insert(-INF);
insert(INF);
int T;
cin >> T;
while (T--) {
int opt, x;
cin >> opt >> x;
if (opt == 1) insert(x);
else if (opt == 2) remove(x);
else if (opt == 3) cout << get_rank_by_key(x) << '\n';
else if (opt == 4) cout << get_key_by_rank(x + 1) << '\n';
else if (opt == 5) cout << tr[get_pre(x)].v << '\n';
else cout << tr[get_suc(x)].v << '\n';
}
return 0;
}
P6136 【模板】普通平衡树(数据加强版)
注意数组要开到 1.1 × 1 0 6 1.1 \times 10 ^ 6 1.1×106。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1100010, INF = (1 << 30) + 1;
struct Node {
int ch[2];
int p, v;