Questions surface:
Resolution:
Clearly a need to modify a modification to the root of the chain, of course, maintain the chain of thought with LCT
Partial results wanted, and had wanted to maintain separate virtual subtree entire subtree information and information found difficult to maintain. Then go out of self-study
We define a point right point selected for its son nodes number $ 1 $
Consider changing the point right point either its chain above the continuous $ 1 $ or continuous $ 2 $, so Splay each node are maintained can be the deepest than $ 1 $ point and not $ 2 $ point, then a range of changes and modifications single point, and engage directly in the Splay on the line
Note that when the update sequence father node, first update with the right son, then left his son
Code:
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int maxn = 500004, inf = 0x3f3f3f3f; inline int read() { int ret, f = 1; char c; while((c=getchar())&&(c<'0'||c>'9'))if(c=='-')f = -1; ret=c-'0'; while((c=getchar())&&(c>='0'&&c<='9')) ret = (ret<<3)+(ret<<1)+c-'0'; return ret*f; } int n, m, f[maxn<<1], a[maxn<<1], root, ans; bool vis[maxn]; struct LCT{ int fa, s[2], val; int nd1, nd2, add; }tr[maxn]; int head[maxn], tot; struct edge{ int nxt, to; }e[maxn]; void Addedge(int x, int y) { e[++tot] = (edge){head[x], y}; head[x] = tot; } void dfs(int x) { for(int i = head[x]; i; i = e[i].nxt) { int id = e[i].to; dfs(id); tr[x].val += (tr[id].val > 1); } tr[x].nd1 = (tr[x].val != 1? x: inf); tr[x].nd2 = (tr[x].val != 2? x: inf); } void update(int x) { int ls = tr[x].s[0], rs = tr[x].s[1]; if(rs && tr[rs].nd1 != inf) tr[x].nd1 = tr[rs].nd1; else if(tr[x].val != 1) tr[x].nd1 = x; else if(ls) tr[x].nd1 = tr[ls].nd1; else tr[x].nd1 = inf; if(rs && tr[rs].nd2 != inf) tr[x].nd2 = tr[rs].nd2; else if(tr[x].val != 2) tr[x].nd2 = x; else if(ls) tr[x].nd2 = tr[ls].nd2; else tr[x].nd2 = inf; } void spread(int x) { int ls = tr[x].s[0], rs = tr[x].s[1]; if(tr[x].add) { if(ls) { tr[ls].add += tr[x].add; tr[ls].val += tr[x].add; swap(tr[ls].nd1, tr[ls].nd2); } if(rs) { tr[rs].add += tr[x].add; tr[rs].val += tr[x].add; swap(tr[rs].nd1, tr[rs].nd2); } tr[x].add = 0; } } bool isroot(int x) { int ff = tr[x].fa; return tr[ff].s[0] != x && tr[ff].s[1] != x; } void Rotate(int x) { int y = tr[x].fa, z = tr[y].fa, k = (tr[y].s[1] == x), w = (tr[z].s[1] == y), son = tr[x].s[k^1]; if(!isroot(y)) tr[z].s[w] = x; tr[y].s[k] = son;tr[son].fa = y; tr[x].s[k^1] = y;tr[y].fa = x; tr[x].fa = z; update(y);update(x); } void PushDown(int x) { if(!isroot(x)) PushDown(tr[x].fa); spread(x); } void Splay(int x) { int y, z; PushDown(x); while(!isroot(x)) { y = tr[x].fa; z = tr[y].fa; if(!isroot(y)) Rotate((tr[y].s[0] == x) ^ (tr[z].s[0] == y)? x: y); Rotate(x); } } void Access(int x) { int pre = 0; while(x) { Splay(x); tr[x].s[1] = pre; update(x); pre = x; x = tr[x].fa; } } int main() { n = read(); for(int i = 1; i <= n; ++i) { int x; for(int j = 1; j <= 3; ++j) { x = read(); if(x <= n) { tr[x].fa = i; Addedge(i, x); vis[x] = 1; } else f[x-n] = i; } } for(int i = 1; i <= (n<<1) + 1; ++i) a[i] = read(), tr[f[i]].val += a[i]; for(int i = 1; i <= n; ++i) if(!vis[i]) { root = i; dfs(i); break; } ans = (tr[root].val > 1); m = read(); for(int i = 1; i <= m; ++i) { int x = read(); x -= n; Access(f[x]); Splay(f[x]); int now = (a[x] == 0? tr[f[x]].nd1: tr[f[x]].nd2), c = (a[x] == 0? 1: -1); if(now != inf) { Splay(now); tr[now].val += c; int rs = tr[now].s[1]; if(rs) { tr[rs].val += c; tr[rs].add += c; swap(tr[rs].nd1, tr[rs].nd2); update(rs); } update(now); } else { tr[f[x]].val += c; tr[f[x]].add += c; ans ^= 1; } a[x] ^= 1; printf("%d\n", ans); } return 0; }