题目链接

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;
}