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

}
bzoj_2819

 

posted @ 2017-09-28 18:39  A_LEAF  阅读(101)  评论(0编辑  收藏  举报