实现正常因为照着视频打的,码风好看是让ChatGPT帮忙改的。
// Splay普通平衡树
#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int read() {
int x = 0, f = 1;
char c;
for (c = getchar(); c < '0' || c > '9'; c = getchar())
if (c == '-') f = -f;
for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
}
class node {
public:
int s[2], fa, val, cnt, size;
node() = default;
void init(int p, int v) {
fa = p, val = v, cnt = size = 1;
}
};
node tr[1000009];
int root, idx;
inline void pushup(int x) {
tr[x].size = tr[tr[x].s[0]].size + tr[tr[x].s[1]].size + tr[x].cnt;
}
inline void rotate(int x) { // 旋转※包括左旋和右旋
int y = tr[x].fa, z = tr[y].fa; // y=father;z=grandfather
int k = tr[y].s[1] == x; // k=x is y's which son
tr[y].s[k] = tr[x].s[k ^ 1];
tr[tr[x].s[k ^ 1]].fa = y;
tr[x].s[k ^ 1] = y;
tr[y].fa = x;
tr[z].s[tr[z].s[1] == y] = x;
tr[x].fa = z;
pushup(y), pushup(x);
}
inline void splay(int x, int k) { // 伸展※核心 (目标:使x成为k的儿子)
while (tr[x].fa != k) {
int y = tr[x].fa, z = tr[y].fa;
if (z != k)
if ((tr[y].s[0] == x && tr[y].s[0] != y) || (tr[y].s[0] != x && tr[y].s[0] == y))
rotate(x);
else
rotate(y);
rotate(x);
}
if (k == 0) root = x;
}
inline void find(int v) {
int x = root;
while (tr[x].s[v > tr[x].val] && v != tr[x].val) x = tr[x].s[v > tr[x].val];
splay(x, 0);
}
inline int getpre(int v) {
find(v);
int x = root;
if (tr[x].val < v) return x;
x = tr[x].s[0];
while (tr[x].s[1]) x = tr[x].s[1];
return x;
}
inline int getsuc(int v) {
find(v);
int x = root;
if (tr[x].val > v) return x;
x = tr[x].s[1];
while (tr[x].s[0]) x = tr[x].s[0];
return x;
}
inline void del(int v) {
int pre = getpre(v), suc = getsuc(v);
splay(pre, 0), splay(suc, pre);
int del = tr[suc].s[0];
if (tr[del].cnt > 1) tr[del].cnt--, splay(del, 0);
else tr[suc].s[0] = 0, splay(suc, 0);
}
inline int getrank(int v) {
find(v);
return tr[tr[root].s[0]].size;
}
inline int getval(int k) {
int x = root;
while (true) {
int y = tr[x].s[0];
if (tr[y].size + tr[x].cnt < k) {
k -= tr[y].size + tr[x].cnt;
x = tr[x].s[1];
} else {
if (tr[y].size >= k) x = tr[x].s[0];
else break;
}
}
splay(x, 0);
return tr[x].val;
}
inline void insert(int v) {
int x = root, p = 0;
while (x && tr[x].val != v) p = x, x = tr[x].s[v > tr[x].val];
if (x) tr[x].cnt++;
else {
x = ++idx;
tr[p].s[v > tr[p].val] = x;
tr[x].init(p, v);
}
splay(x, 0);
}
signed main() {
insert(0x80000000), insert(0x7fffffff);
int n = read();
while (n--) {
int op = read(), x = read();
switch (op) {
case 1:
insert(x);
break;
case 2:
del(x);
break;
case 3:
printf("%lld\n", getrank(x));
break;
case 4:
printf("%lld\n", getval(x + 1));
break;
case 5:
printf("%lld\n", tr[getpre(x)].val);
break;
case 6:
printf("%lld\n", tr[getsuc(x)].val);
break;
}
}
}
显然连样例都没过,所以应该比较容易查错。
^_^