题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=2819
题解
可以发现每堆石子的sg就是石子的个数,用树链剖分维护石子个数的异或。
代码
#include <cstdio>
#include <algorithm>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=500000;
int n,m,w[maxn+10],pre[maxn*2+10],now[maxn+10],son[maxn*2+10],tot,wson[maxn+10],top[maxn+10],dfn[maxn+10],size[maxn+10],cnt,fa[maxn+10],deep[maxn+10];
namespace ta
{
int val[maxn+10];
int lowbit(int x)
{
return x&(-x);
}
int modify(int pos,int v)
{
while(pos<=n)
{
val[pos]^=v;
pos+=lowbit(pos);
}
return 0;
}
int getval(int pos)
{
if(pos<=0)
{
return 0;
}
int res=0;
while(pos)
{
res^=val[pos];
pos-=lowbit(pos);
}
return res;
}
}
int ins(int a,int b)
{
pre[++tot]=now[a];
now[a]=tot;
son[tot]=b;
return 0;
}
int dfsfirst(int u,int father)
{
size[u]=1;
fa[u]=father;
for(int i=now[u]; i; i=pre[i])
{
int v=son[i];
if(v!=father)
{
deep[v]=deep[u]+1;
dfsfirst(v,u);
size[u]+=size[v];
if((wson[u]==0)||(size[wson[u]]<size[v]))
{
wson[u]=v;
}
}
}
return 0;
}
int dfssecond(int u,int topfather)
{
top[u]=topfather;
dfn[u]=++cnt;
if(wson[u]==0)
{
return 0;
}
dfssecond(wson[u],topfather);
for(int i=now[u]; i; i=pre[i])
{
int v=son[i];
if((v!=fa[u])&&(v!=wson[u]))
{
dfssecond(v,v);
}
}
return 0;
}
int getans(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
{
std::swap(x,y);
}
ans^=ta::getval(dfn[x])^ta::getval(dfn[top[x]]-1);
x=fa[top[x]];
}
if(deep[x]<deep[y])
{
std::swap(x,y);
}
ans^=ta::getval(dfn[x])^ta::getval(dfn[y]-1);
return ans;
}
int main()
{
n=read();
for(int i=1; i<=n; ++i)
{
w[i]=read();
}
for(int i=1; i<n; ++i)
{
int a=read(),b=read();
ins(a,b);
ins(b,a);
}
deep[1]=1;
dfsfirst(1,0);
dfssecond(1,1);
for(int i=1; i<=n; ++i)
{
ta::modify(dfn[i],w[i]);
}
m=read();
while(m--)
{
char ch=getchar();
while((ch!='Q')&&(ch!='C'))
{
ch=getchar();
}
int x=read(),y=read();
if(ch=='Q')
{
puts(getans(x,y)?"Yes":"No");
}
else
{
ta::modify(dfn[x],y^w[x]);
w[x]=y;
}
}
return 0;
}