1. 程式人生 > >bzoj 2819 Nim

bzoj 2819 Nim

src size lose cdd uil ont clu getc sed

定理:

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

bzoj 2819 Nim