洛谷P3391 文艺平衡树 (Splay模板)
模板题。
打区间翻转标记,要翻转区间[l, r] ,需要将l - 1翻转到根,再将r + 1翻转至根节点的儿子,因此要设立首尾哨兵。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 10, inf = 1e9 + 10; 4 int lc[N], rc[N], fa[N], sze[N], vi[N], pos[N], a[N]; 5 int n, m, rt, T, x, y; 6 inline int read() { 7 int x = 0, f = 1; char ch = getchar(); 8 while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();} 9 while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar(); 10 return x * f; 11 } 12 namespace Splay { 13 void pushup(int x) { 14 sze[x] = sze[lc[x]] + sze[rc[x]] + 1; 15 } 16 int build(int lst, int l, int r) { 17 if (l > r) return 0; 18 int mid = (l + r) >> 1, x = ++ T; 19 fa[x] = lst; pos[x] = 0; vi[x] = a[mid]; 20 lc[x] = build(x, l, mid - 1); 21 rc[x] = build(x, mid + 1, r); 22 pushup(x); 23 return x; 24 } 25 void pushdown(int x) {//下传翻转标记 26 if (x && pos[x]) { 27 pos[lc[x]] ^= 1; 28 pos[rc[x]] ^= 1; 29 swap(lc[x], rc[x]); 30 pos[x] = 0; 31 } 32 } 33 bool Wrt(int x) { 34 return rc[fa[x]] == x; 35 } 36 void rot(int x) { 37 int y = fa[x], z = fa[y]; 38 pushdown(y), pushdown(x); 39 int b = (lc[y] == x) ? rc[x] : lc[x]; 40 //b是x的儿子,其方向要与x相反 41 fa[x] = z, fa[y] = x; 42 if (b) fa[b] = y;//对fa[]修改 43 if (z) (y == lc[z] ? lc[z] : rc[z]) = x; 44 if (x == lc[y]) rc[x] = y, lc[y] = b; 45 else lc[x] = y, rc[y] = b;//对左右儿子修改 46 pushup(y), pushup(x); 47 } 48 void splay(int x, int tar) { 49 while (fa[x] != tar) { 50 if (fa[fa[x]] != tar) 51 Wrt(x) == Wrt(fa[x]) ? rot(fa[x]) : rot(x); 52 rot(x); 53 } 54 if (!tar) rt = x; 55 } 56 int Find(int k) {//查找第k个数,返回其节点编号 57 int x = rt, y = k; 58 while(x) { 59 pushdown(x); 60 if (y <= sze[lc[x]]) x = lc[x]; 61 else { 62 y -=sze[lc[x]] + 1; 63 if (!y) return x; 64 x = rc[x]; 65 } 66 } 67 } 68 } 69 using namespace Splay; 70 void Print(int x) { 71 pushdown(x); 72 if (lc[x]) Print(lc[x]); 73 if (vi[x] != -inf && vi[x] != inf) 74 printf("%d ", vi[x]); 75 if (rc[x]) Print(rc[x]); 76 } 77 int main() { 78 n = read(), m = read(); 79 a[1] = -inf, a[n + 2] = inf; 80 for (int i = 1; i <= n; i ++) a[i + 1] = i; 81 rt = build(0, 1, n + 2); 82 while (m --) { 83 int tx = Find(read()); 84 int ty = Find(read() + 2); 85 splay(tx, 0); 86 splay(ty, tx); 87 pos[lc[rc[rt]]] ^= 1; 88 } 89 Print(rt); 90 return 0; 91 }