#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;
}