对于splay核心是旋转和伸展,其他操作基本都是利用伸展的特性:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define INF 0x3f3f3f3f 4 #define M(a, b) memset(a, b, sizeof(a)) 5 const int N = 5e4 + 5; 6 int ch[N][2], p[N], num[N], sz, rt; 7 8 void rotate(int x, int &k) { 9 int y = p[x], z = p[y], d = ch[y][1]==x; 10 if (y == k) k = x; 11 else ch[z][ch[z][1]==y] = x; 12 p[ch[x][d^1]] = y; p[y] = x; p[x] = z; 13 ch[y][d] = ch[x][d^1]; ch[x][d^1] = y; 14 } 15 16 void splay(int x, int &k) { 17 while (x != k) { 18 int y = p[x], z = p[y]; 19 if (y != k) { 20 if ((ch[z][0]==y)^(ch[y][0]==x)) rotate(x, k); 21 else rotate(y, k); 22 } 23 rotate(x, k); 24 } 25 } 26 27 void insert(int x, int &k, int fa) { 28 if (k == 0) {k = ++sz; num[k] = x; p[k] = fa; splay(k, rt); return;} 29 if (x < num[k]) insert(x, ch[k][0], k); 30 else insert(x, ch[k][1], k); 31 } 32 33 void split(int &k, int &k1, int nth) { 34 splay(nth, k); 35 k1 = ch[k][1]; 36 p[k1] = 0; ch[k][1] = 0; 37 }