bzoj3637 Query on a tree VI
Posted 逢山开路 遇水架桥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3637 Query on a tree VI相关的知识,希望对你有一定的参考价值。
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3637
【题解】
LCT维护连通性问题。
发现如果直接按题目说的复杂度就是错的了(因为依赖于度数)
所以我们分黑白建树,黑的里存白->黑和黑->黑两种边,白的类似。
那么每次只会改变两棵树内的各一个。
因为LCT维护连通性所以需要记录除了主链外的其他size。
在access的时候即可记录。
这个link和cut很迷啊暂时没看懂啊(逃)参考别人代码
留坑
# include <stdio.h> # include <string.h> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, head[M], nxt[M], to[M], tot=0; bool color[M]; inline void add(int u, int v) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; } inline void adde(int u, int v) {add(u, v), add(v, u);} struct LCT { int co, ch[M][2], fa[M], sz[M], SZ[M]; bool rev[M]; inline void change(int x, int d) { sz[x] += d; SZ[x] += d; } inline void set(int n, int _co) { co = _co; memset(ch, 0, sizeof ch); memset(fa, 0, sizeof fa); memset(rev, 0, sizeof rev); memset(sz, 0, sizeof sz); memset(SZ, 0, sizeof SZ); if(!co) for (int i=1; i<=n; ++i) change(i, 1); } # define ls ch[x][0] # define rs ch[x][1] inline void up(int x) { if(!x) return; sz[x] = sz[ls] + sz[rs] + SZ[x]; } # undef ls # undef rs inline bool isrt(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; } inline void rotate(int x) { int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1; if(!isrt(y)) ch[z][ch[z][1] == y] = x; fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z; ch[y][ls] = ch[x][rs]; ch[x][rs] = y; up(y); up(x); } inline void splay(int x) { while(!isrt(x)) { int y = fa[x], z = fa[y]; if(!isrt(y)) { if((ch[y][0] == x)^(ch[z][0] == y)) rotate(x); else rotate(y); } rotate(x); } } inline int access(int x) { int t = 0; for (; x; t=x, x=fa[x]) { splay(x); if(ch[x][1]) SZ[x] += sz[ch[x][1]]; if(t) SZ[x] -= sz[t]; ch[x][1] = t; up(x); } return t; } inline void link(int x, int y) { if(!y) return; access(y); splay(y); splay(x); fa[x] = y; ch[y][1] = x; up(y); } inline void cut(int x, int y) { if(!y) return; access(x); splay(x); fa[ch[x][0]] = 0, ch[x][0] = 0; up(x); } inline int find(int x) { access(x); splay(x); while(ch[x][0]) x = ch[x][0]; return x; } inline void getans(int x) { int t = find(x); splay(t); if(color[t] == co) printf("%d\n", sz[t]); else printf("%d\n", sz[ch[t][1]]); } }T[2]; // T[0]: black, T[1]: white // color0: black, color1: white int fa[M]; inline void dfs(int x, int father) { fa[x] = father; for (int i=head[x]; i; i=nxt[i]) { if(to[i] == father) continue; T[0].link(to[i], x); dfs(to[i], x); } } int main() { scanf("%d", &n); for (int i=1, u, v; i<n; ++i) { scanf("%d%d", &u, &v); adde(u, v); } T[0].set(n, 0); T[1].set(n, 1); dfs(1, 0); // for (int i=1; i<=n; ++i) T[0].getans(i); puts("\n==============="); int q; scanf("%d", &q); int opt, x; while(q--) { scanf("%d%d", &opt, &x); if(opt == 0) T[color[x]].getans(x); else { T[color[x]].cut(x, fa[x]); T[color[x]].change(x, -1); color[x] ^= 1; T[color[x]].change(x, 1); T[color[x]].link(x, fa[x]); } } return 0; }
以上是关于bzoj3637 Query on a tree VI的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解
BZOJ1803Spoj1487 Query on a tree III 主席树+DFS序