bzoj 2819 Nim
定理:
Nim问题定理:所有堆石子数^和==0是平衡的
平衡的后手赢 不平衡的先手赢
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <iostream> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=500006; inline char readchar() { char q=getchar(); while(q!='Q'&&q!='C')q=getchar(); return q; } inline int read() { char q=getchar();int ans=0; while(q<'0'||q>'9')q=getchar(); while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();} return ans; } struct son { int v,next; }a1[N*2]; int first[N*2],e; int n,m; int v[N]; void addbian(int u,int v) { a1[e].v=v; a1[e].next=first[u]; first[u]=e++; } int fa[N],dep[N],son[N],size[N]; void dfs1(int x) { int temp; size[x]=1; for(int i=first[x];i!=-1;i=a1[i].next) { temp=a1[i].v; if(temp==fa[x]) continue; fa[temp]=x; dep[temp]=dep[x]+1; dfs1(temp); size[x]+=size[temp]; if(size[son[x]]<size[temp]) son[x]=temp; } } int zheng[N],now,top[N],fan[N]; void dfs2(int x,int tp) { zheng[x]=++now; fan[now]=x; top[x]=tp; if(son[x]) dfs2(son[x],tp); int temp; for(int i=first[x];i!=-1;i=a1[i].next) { temp=a1[i].v; if(temp==fa[x]||temp==son[x]) continue; dfs2(temp,temp); } } int a[N*5]; void pushup(int x) { a[x]=a[x<<1]^a[x<<1|1]; } void build(int l,int r,int x) { if(l==r) { a[x]=v[fan[l]]; return ; } int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); pushup(x); } int qq(int L,int R,int l,int r,int x) { if(L<=l&&r<=R) return a[x]; int mid=(l+r)>>1,ans=0; if(L<=mid) ans^=qq(L,R,l,mid,x<<1); if(mid<R) ans^=qq(L,R,mid+1,r,x<<1|1); return ans; } void add(int pos,int c,int l,int r,int x) { if(l==r) { a[x]=c; return ; } int mid=(l+r)>>1; if(pos<=mid) add(pos,c,l,mid,x<<1); else add(pos,c,mid+1,r,x<<1|1); pushup(x); } int QQ(int x,int y) { int tx=x,ty=y; int fx=top[x],fy=top[y]; int sum=0; while(fx!=fy) { if(dep[fx]<dep[fy]) { swap(fx,fy); swap(x,y); } sum^=qq(zheng[fx],zheng[x],1,n,1); x=fa[fx]; fx=top[x]; } if(dep[x]>dep[y]) swap(x,y); sum^=qq(zheng[x],zheng[y],1,n,1); return sum!=0; } void ADD(int pos,int c) { add(zheng[pos],c,1,n,1); } int main(){ //freopen("in.in","r",stdin); mem(first,-1); n=read(); for(int i=1;i<=n;++i) v[i]=read(); int tin1,tin2; for(int i=1;i<n;++i) { tin1=read();tin2=read(); addbian(tin1,tin2); addbian(tin2,tin1); } dfs1(1); dfs2(1,1); build(1,n,1); m=read(); char op; for(int i=1;i<=m;++i) { op=readchar(); tin1=read();tin2=read(); if(op=='Q') { if(QQ(tin1,tin2)) printf("Yes\n"); else printf("No\n"); } else ADD(tin1,tin2); } }