Given a tree, each node is a pile of stones and two operations are given:
1. Change the number of stones on node X.
2. Use all heap stones on the path from X to Y to play a nim game and ask if there is a winning strategy
Nim games have a winning strategy. The only condition is that the number of stones in all stacks is different or not zero.
The first thing we can do is to split the tree chain. Then, the question kindly tells us that deep search will blow up the stack. So we can select wide search for the tree chain.
BFS searches from left to right, and traces from right to left. It is sufficient to repeat BFS once.
You can also apply the zkw line segment tree to the single-point modification interval query.
But in fact this question does not need so much trouble to have a simpler way to see http://dzy493941464.is-programmer.com/posts/40428.html
Because of the need to write the system stack, I am too lazy to write 0.0, and I think that the first time I wrote the system stack at the time of the provincial election, 0.0 was actually over 0.0.
Just paste a tree link to the split version. How can this problem be solved when the code is written more slowly? 0.0
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 500100using namespace std;struct abcd{ int to,next;}table[M<<1];int head[M],tot;void add(int x,int y){ table[++tot].to=y; table[tot].next=head[x]; head[x]=tot;}int n,m,q,tree[1049000],f[M],pos[M],dpt[M],siz[M],son[M],top[M],fa[M],cnt,queue[M],r,h;void bfs(){ int i,j,x; queue[++r]=1; while(r!=h) { x=queue[++h]; dpt[x]=dpt[fa[x]]+1; siz[x]=1; for(i=head[x];i;i=table[i].next) { if(table[i].to==fa[x]) continue; fa[table[i].to]=x; queue[++r]=table[i].to; } } for(i=n;i;i--) { x=queue[i]; siz[fa[x]]+=siz[x]; if(siz[x]>siz[son[fa[x]]]) son[fa[x]]=x; } for(i=1;i<=n;i++) { x=queue[i]; if(son[fa[x]]==x) top[x]=top[fa[x]]; else { top[x]=x; for(j=x;j;j=son[j]) pos[j]=++cnt; } }}void Build_tree(){ for(int i=q-1;i;i--) tree[i]=tree[i<<1]^tree[i<<1|1];}void change(int x,int y){ for(tree[x+=q]=y,x>>=1;x;x>>=1) tree[x]=tree[x<<1]^tree[x<<1|1];}int getans(int x,int y){ int re=0; for(x+=q-1,y+=q+1;x^y^1;x>>=1,y>>=1) { if(~x&1)re^=tree[x^1]; if( y&1)re^=tree[y^1]; } return re;}int query(int x,int y){ int re=0,fx=top[x],fy=top[y]; while(fx!=fy) { if(dpt[fx]<dpt[fy]) swap(x,y),swap(fx,fy); re^=getans(pos[fx],pos[x]); x=fa[fx];fx=top[x]; } if(dpt[x]<dpt[y]) swap(x,y); re^=getans(pos[y],pos[x]); return re;}int main(){ int i,x,y; char p[10]; cin>>n; for(q=1;q<=n+1;q<<=1); for(i=1;i<=n;i++) scanf("%d",&f[i]); for(i=1;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } bfs(); for(i=1;i<=n;i++) tree[pos[i]+q]=f[i]; Build_tree(); cin>>m; for(i=1;i<=m;i++) { scanf("%s%d%d",p,&x,&y); if(p[0]=='C') change(pos[x],y); else printf("%s\n",query(x,y)==0?"No":"Yes"); }}
Bzoj 2819 Nim tree link partitioning/DFS sequence + LCA + tree Array