题意:
解:
发现我们每次染的都是不同的颜色,那么用lct维护的话一个颜色就会在一个splay里。染色是access。
维护每个节点到根路径上的虚边数量。
虚边的切换只会在access和link中出现。于是access的时候顺便修改那个子树。lct上啥也不用维护。
查询链可以用两端点减去lca。
1 #include <bits/stdc++.h> 2 3 const int N = 100010, INF = 0x3f3f3f3f; 4 5 struct Edge { 6 int nex, v; 7 }edge[N << 1]; int tp; 8 9 int e[N], n, siz[N], pos[N], id[N], d[N], num, top[N], father[N], son[N]; /// tree 10 int fa[N], s[N][2], stk[N], Top; /// lct 11 bool rev[N]; 12 int large[N << 2], tag[N << 2]; /// seg 13 14 inline void add(int x, int y) { 15 tp++; 16 edge[tp].v = y; 17 edge[tp].nex = e[x]; 18 e[x] = tp; 19 return; 20 } 21 22 void DFS_1(int x, int f) { /// father siz son d 23 siz[x] = 1; 24 fa[x] = father[x] = f; 25 for(int i = e[x]; i; i = edge[i].nex) { 26 int y = edge[i].v; 27 if(y == f) continue; 28 d[y] = d[x] + 1; 29 DFS_1(y, x); 30 siz[x] += siz[y]; 31 if(siz[y] > siz[son[x]]) { 32 son[x] = y; 33 } 34 } 35 return; 36 } 37 38 void DFS_2(int x, int f) { /// top id pos 39 top[x] = f; 40 pos[x] = ++num; 41 id[num] = x; 42 if(son[x]) DFS_2(son[x], f); 43 for(int i = e[x]; i; i = edge[i].nex) { 44 int y = edge[i].v; 45 if(y == father[x] || y == son[x]) continue; 46 DFS_2(y, y); 47 } 48 return; 49 } 50 51 inline void Pushdown(int o) { 52 if(tag[o]) { 53 int ls = o << 1, rs = o << 1 | 1; 54 tag[ls] += tag[o]; 55 tag[rs] += tag[o]; 56 large[ls] += tag[o]; 57 large[rs] += tag[o]; 58 tag[o] = 0; 59 } 60 return; 61 } 62 63 void build(int l, int r, int o) { 64 if(l == r) { 65 large[o] = d[id[r]]; 66 return; 67 } 68 int mid = (l + r) >> 1; 69 build(l, mid, o << 1); 70 build(mid + 1, r, o << 1 | 1); 71 large[o] = std::max(large[o << 1], large[o << 1 | 1]); 72 return; 73 } 74 75 void add(int L, int R, int v, int l, int r, int o) { 76 if(L <= l && r <= R) { 77 large[o] += v; 78 tag[o] += v; 79 return; 80 } 81 Pushdown(o); 82 int mid = (l + r) >> 1; 83 if(L <= mid) add(L, R, v, l, mid, o << 1); 84 if(mid < R) add(L, R, v, mid + 1, r, o << 1 | 1); 85 large[o] = std::max(large[o << 1], large[o << 1 | 1]); 86 return; 87 } 88 89 int getMax(int L, int R, int l, int r, int o) { 90 if(L <= l && r <= R) return large[o]; 91 int mid = (l + r) >> 1, ans = -INF; 92 Pushdown(o); 93 if(L <= mid) ans = std::max(ans, getMax(L, R, l, mid, o << 1)); 94 if(mid < R) ans = std::max(ans, getMax(L, R, mid + 1, r, o << 1 | 1)); 95 return ans; 96 } 97 98 int ask(int p, int l, int r, int o) { 99 if(l == r) return large[o]; 100 Pushdown(o); 101 int mid = (l + r) >> 1; 102 if(p <= mid) return ask(p, l, mid, o << 1); 103 else return ask(p, mid + 1, r, o << 1 | 1); 104 } 105 106 inline void pushdown(int x) { 107 if(rev[x]) { 108 std::swap(s[x][0], s[x][1]); 109 if(s[x][0]) rev[s[x][0]] ^= 1; 110 if(s[x][1]) rev[s[x][1]] ^= 1; 111 rev[x] = 0; 112 } 113 return; 114 } 115 116 inline void pushup(int x) { 117 return; 118 } 119 120 inline bool no_root(int x) { 121 return (s[fa[x]][0] == x) || (s[fa[x]][1] == x); 122 } 123 124 inline void rotate(int x) { 125 int y = fa[x]; 126 int z = fa[y]; 127 bool f = (s[y][1] == x); 128 129 fa[x] = z; 130 if(no_root(y)) { 131 s[z][s[z][1] == y] = x; 132 } 133 s[y][f] = s[x][!f]; 134 if(s[x][!f]) { 135 fa[s[x][!f]] = y; 136 } 137 s[x][!f] = y; 138 fa[y] = x; 139 140 pushup(y); 141 return; 142 } 143 144 inline void splay(int x) { 145 int y = x; 146 stk[++Top] = y; 147 while(no_root(y)) { 148 y = fa[y]; 149 stk[++Top] = y; 150 } 151 while(Top) { 152 pushdown(stk[Top]); 153 Top--; 154 } 155 156 y = fa[x]; 157 int z = fa[y]; 158 while(no_root(x)) { 159 if(no_root(y)) { 160 (s[z][1] == y) ^ (s[y][1] == x) ? 161 rotate(x) : rotate(y); 162 } 163 rotate(x); 164 y = fa[x]; 165 z = fa[y]; 166 } 167 pushup(x); 168 return; 169 } 170 171 inline void change(int x, int v) { 172 pushdown(x); 173 while(s[x][0]) { 174 x = s[x][0]; 175 pushdown(x); 176 } 177 /// x 178 add(pos[x], pos[x] + siz[x] - 1, v, 1, n, 1); 179 return; 180 } 181 182 inline void access(int x) { 183 int y = 0; 184 while(x) { 185 splay(x); 186 if(s[x][1]) change(s[x][1], 1); 187 if(y) change(y, -1); 188 s[x][1] = y; 189 pushup(x); 190 y = x; 191 x = fa[x]; 192 } 193 return; 194 } 195 196 inline int lca(int x, int y) { 197 while(top[x] != top[y]) { 198 if(d[top[x]] < d[top[y]]) { 199 y = father[top[y]]; 200 } 201 else { 202 x = father[top[x]]; 203 } 204 } 205 return d[x] < d[y] ? x : y; 206 } 207 208 inline int ask(int x, int y) { 209 //printf("ask : %d %d lca %d ", x, y, lca(x, y)); 210 //printf("ask : %d + %d - 2 * %d ", ask(pos[x], 1, n, 1), ask(pos[y], 1, n, 1), ask(pos[lca(x, y)], 1, n, 1)); 211 return ask(pos[x], 1, n, 1) + ask(pos[y], 1, n, 1) - 2 * ask(pos[lca(x, y)], 1, n, 1); 212 } 213 214 inline int query(int x) { 215 return getMax(pos[x], pos[x] + siz[x] - 1, 1, n, 1); 216 } 217 218 int main() { 219 int m; 220 scanf("%d%d", &n, &m); 221 for(int i = 1, x, y; i < n; i++) { 222 scanf("%d%d", &x, &y); 223 add(x, y); add(y, x); 224 } 225 /// init 226 DFS_1(1, 0); 227 DFS_2(1, 1); 228 build(1, n, 1); 229 230 for(int i = 1, f, x, y; i <= m; i++) { 231 scanf("%d%d", &f, &x); 232 if(f == 1) { /// change 233 access(x); 234 } 235 else if(f == 2) { 236 scanf("%d", &y); 237 printf("%d ", ask(x, y) + 1); 238 } 239 else { /// f == 3 240 printf("%d ", query(x) + 1); 241 } 242 } 243 return 0; 244 }