1. 程式人生 > >Luogu 3690 LCT - 模板

Luogu 3690 LCT - 模板

void fin return getc blank 分享 spl () ring

推薦幾篇比較好的博客:

FlashHu 的 講解比較好 : 傳送門

Candy 的 代碼~ : 傳送門

以及神犇Angel_Kitty的 學習筆記: 傳送門

Code

技術分享圖片
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define rd read()
  5 using namespace std;
  6 
  7 const int N = 1e5 + 5;
  8 int n, m;
  9 
 10 int read() {
11 int X = 0, p = 1; char c =getchar(); 12 for (; c > 9 || c < 0; c = getchar()) 13 if (c == -) p = -1; 14 for (; c >= 0 && c <= 9; c = getchar()) 15 X = X * 10 + c - 0; 16 return X * p; 17 } 18 19 namespace LCT { 20 int
f[N], ch[N][2], rev[N], val[N], sum[N]; 21 22 #define lc(x) ch[x][0] 23 #define rc(x) ch[x][1] 24 25 int isroot(int x) { 26 return ch[f[x]][0] != x && ch[f[x]][1] != x; 27 } 28 29 int get(int x) { 30 return ch[f[x]][1] == x; 31 } 32 33
void up(int x) { 34 sum[x] = sum[lc(x)] ^ sum[rc(x)] ^ val[x]; 35 } 36 37 void rerv(int x) { 38 swap(rc(x), lc(x)); 39 rev[x] ^= 1; 40 } 41 42 void pushdown(int x) { 43 if (rev[x]) { 44 if (lc(x)) rerv(lc(x)); 45 if (rc(x)) rerv(rc(x)); 46 rev[x] = 0; 47 } 48 } 49 50 void pd(int x) { 51 if (!isroot(x)) 52 pd(f[x]); 53 pushdown(x); 54 } 55 56 void rotate(int x) { 57 int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1]; 58 if (!isroot(old)) ch[oldf][get(old)] = x; 59 ch[x][get(x) ^ 1] = old; 60 ch[old][get(x)] = son; 61 f[x] = oldf; f[old] = x; f[son] = old; 62 up(old); up(x); 63 } 64 65 void splay(int x) { 66 pd(x); 67 for (; !isroot(x); rotate(x)) 68 if (!isroot(f[x])) 69 rotate(get(x) == get(f[x]) ? f[x] : x); 70 } 71 72 void access(int x) { 73 for (int y = 0; x; y = x, x = f[x]) 74 splay(x), rc(x) = y, up(x); 75 } 76 77 void mroot(int x) { 78 access(x); splay(x); rerv(x); 79 } 80 81 int findr(int x) { 82 access(x); splay(x); 83 while (lc(x)) { 84 pushdown(x); 85 x = lc(x); 86 } 87 return x; 88 } 89 90 void link(int x, int y) { 91 mroot(x); 92 if (findr(y) == x) 93 return; 94 f[x] = y; 95 } 96 97 void cut(int x, int y) { 98 mroot(x); 99 if(findr(y) != x || f[x] != y || ch[x][1]) 100 return; 101 f[x] = ch[y][0] = 0; 102 up(y); 103 } 104 } 105 using namespace LCT; 106 107 int main() 108 { 109 n = rd; m = rd; 110 for (int i = 1; i <= n; ++i) 111 val[i] = rd; 112 for (int i = 1; i <= m; ++i) { 113 int k, u, v; 114 k = rd; 115 if (k == 0) { 116 u = rd; v = rd; 117 mroot(u); access(v); splay(v); 118 printf("%d\n", sum[v]); 119 } 120 if (k == 1) { 121 u = rd, v = rd; 122 link(u, v); 123 } 124 if (k == 2) { 125 u = rd; v = rd; 126 cut(u, v); 127 } 128 if (k == 3) { 129 u = rd; v = rd; 130 val[u] = v; 131 up(u); splay(u); 132 } 133 } 134 }
View Code

Luogu 3690 LCT - 模板