题意:给定森林,可以把两棵树连起来或者询问链上第k大。
解:启发式合并。
我一开始想到了启发式合并但是发现这样做之后一棵子树就不是一段连续的区间了,那就不能子树xxx了,很迷惘。
后来看了题解发现本来就不需要子树是连续区间......
每次把小的树暴力DFS重构fa[][]和重建主席树。
调了半天是因为lastans没有套上X[]......
注意并查集merge的时候可能有元素为0。无视之即可。
1 #include <cstdio> 2 #include <algorithm> 3 4 const int N = 80010, M = 30000010; 5 6 struct Edge { 7 int nex, v; 8 }edge[N << 1]; int top; 9 10 int X[N], e[N], n, val[N], temp, pw[N], fa[N][20], tot, vis[N], father[N], siz[N], d[N], rt[N]; 11 int sum[M], ls[M], rs[M]; 12 char str[3]; 13 14 int find(int x) { 15 if(father[x] == x) { 16 return x; 17 } 18 return father[x] = find(father[x]); 19 } 20 21 inline void merge(int x, int y) { 22 if(!x || !y) { 23 return; 24 } 25 x = find(x); 26 y = find(y); 27 if(x == y) { 28 return; 29 } 30 father[x] = y; 31 siz[y] += siz[x]; 32 return; 33 } 34 35 inline bool check(int x, int y) { 36 return find(x) == find(y); 37 } 38 39 inline void add(int x, int y) { 40 top++; 41 edge[top].v = y; 42 edge[top].nex = e[x]; 43 e[x] = top; 44 return; 45 } 46 47 void add(int x, int &y, int p, int l, int r) { 48 if(!y || y == x) { 49 y = ++tot; 50 sum[y] = sum[x]; 51 ls[y] = ls[x]; 52 rs[y] = rs[x]; 53 } 54 if(l == r) { 55 sum[y]++; 56 return; 57 } 58 int mid = (l + r) >> 1; 59 if(p <= mid) { 60 add(ls[x], ls[y], p, l, mid); 61 } 62 else { 63 add(rs[x], rs[y], p, mid + 1, r); 64 } 65 sum[y] = sum[ls[y]] + sum[rs[y]]; 66 return; 67 } 68 69 void DFS(int x, int f) { 70 merge(x, f); 71 vis[x] = 1; 72 fa[x][0] = f; 73 d[x] = d[f] + 1; 74 for(int j = 1; j <= pw[n]; j++) { 75 fa[x][j] = fa[fa[x][j - 1]][j - 1]; 76 } 77 rt[x] = 0; 78 add(rt[f], rt[x], val[x], 1, temp); 79 for(int i = e[x]; i; i = edge[i].nex) { 80 int y = edge[i].v; 81 if(y == f) { 82 continue; 83 } 84 DFS(y, x); 85 } 86 return; 87 } 88 89 inline void link(int x, int y) { 90 if(check(x, y)) { 91 printf("E1"); 92 exit(0); 93 } 94 if(siz[find(x)] < siz[find(y)]) { 95 std::swap(x, y); 96 } 97 DFS(y, x); 98 add(x, y); 99 add(y, x); 100 return; 101 } 102 103 inline int lca(int x, int y) { 104 if(d[x] > d[y]) { 105 std::swap(x, y); 106 } 107 int t = pw[n]; 108 while(t >= 0 && d[x] != d[y]) { 109 if(d[fa[y][t]] >= d[x]) { 110 y = fa[y][t]; 111 } 112 t--; 113 } 114 if(x == y) { 115 return x; 116 } 117 t = pw[n]; 118 while(t >= 0 && fa[x][0] != fa[y][0]) { 119 if(fa[x][t] != fa[y][t]) { 120 x = fa[x][t]; 121 y = fa[y][t]; 122 } 123 t--; 124 } 125 return fa[x][0]; 126 } 127 128 int Ask(int x, int y, int z, int w, int k, int l, int r) { 129 if(l == r) { 130 return r; 131 } 132 int mid = (l + r) >> 1, s = 0; 133 s = sum[ls[x]] + sum[ls[y]] - sum[ls[z]] - sum[ls[w]]; 134 if(k <= s) { 135 return Ask(ls[x], ls[y], ls[z], ls[w], k, l, mid); 136 } 137 else { 138 return Ask(rs[x], rs[y], rs[z], rs[w], k - s, mid + 1, r); 139 } 140 } 141 142 inline int ask(int x, int y, int k) { 143 if(!check(x, y)) { 144 printf("E2"); 145 exit(0); 146 } 147 int z = lca(x, y); 148 if(d[x] + d[y] - d[z] - d[z] + 1 < k) { 149 printf("E3"); 150 exit(0); 151 } 152 return Ask(rt[x], rt[y], rt[z], rt[fa[z][0]], k, 1, temp); 153 } 154 155 int main() { 156 157 //freopen("in.in", "r", stdin); 158 //freopen("my.out", "w", stdout); 159 160 int m, q; 161 scanf("%d", &n); 162 scanf("%d%d%d", &n, &m, &q); 163 for(int i = 1; i <= n; i++) { 164 scanf("%d", &val[i]); 165 X[++temp] = val[i]; 166 siz[i] = 1; 167 father[i] = i; 168 } 169 for(int i = 1, x, y; i <= m; i++) { 170 scanf("%d%d", &x, &y); 171 add(x, y); 172 add(y, x); 173 } 174 for(int i = 2; i <= n; i++) { 175 pw[i] = pw[i >> 1] + 1; 176 } 177 std::sort(X + 1, X + temp + 1); 178 temp = std::unique(X + 1, X + temp + 1) - X - 1; 179 for(int i = 1; i <= n; i++) { 180 val[i] = std::lower_bound(X + 1, X + temp + 1, val[i]) - X; 181 } 182 for(int i = 1; i <= n; i++) { 183 if(!vis[i]) { 184 DFS(i, 0); 185 } 186 } 187 /// build 188 189 int lastans = 0; 190 for(int i = 1, x, y, k; i <= q; i++) { 191 scanf("%s%d%d", str, &x, &y); 192 if(str[0] == 'L') { // link 193 link(x ^ lastans, y ^ lastans); 194 } 195 else { 196 scanf("%d", &k); 197 lastans = X[ask(x ^ lastans, y ^ lastans, k ^ lastans)]; 198 printf("%d ", lastans); 199 } 200 } 201 202 return 0; 203 }