BZOJ2819 Nim

版权声明:蒟蒻Blog随意转载 https://blog.csdn.net/a1799342217/article/details/81740925

树链剖分

题目传送门

Nim游戏中先手必胜的结论为每堆石子数的异或和不为0。
那么这道题就变成板子题了。

代码:

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 500005
#define F inline
using namespace std;
struct edge{ int nxt,to; }ed[N];
struct tree{ int l,r,x; }t[N<<2];
int n,m,k,p,h[N],fa[N],dep[N],tp[N],sz[N],to[N],id[N],in[N],a[N];
F char readc(){
    static char buf[100000],*l=buf,*r=buf;
    if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
    return l==r?EOF:*l++;
}
F int _read(){
    int x=0; char ch=readc();
    while (!isdigit(ch)&&!isupper(ch)) ch=readc();
    if (isupper(ch)) return ch;
    while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
    return x;
}
#define addedge(x,y) ed[++k]=(edge){h[x],y},h[x]=k
void dfs1(int x){
    dep[x]=dep[fa[x]]+1,sz[x]=1;
    for (int i=h[x],v;i;i=ed[i].nxt)
        if ((v=ed[i].to)!=fa[x]){
            fa[v]=x,dfs1(v),sz[x]+=sz[v];
            if (sz[to[x]]<sz[v]) to[x]=v;
        }
}
void dfs2(int x){
    if (to[in[id[x]=++p]=x]) tp[to[x]]=tp[x],dfs2(to[x]);
    for (int i=h[x],v;i;i=ed[i].nxt)
        if ((v=ed[i].to)!=fa[x]&&v!=to[x])
            tp[v]=v,dfs2(v);
}
void build(int x,int l,int r){
    t[x].l=l,t[x].r=r; int mid=l+r>>1;
    if (l==r) return void(t[x].x=a[in[l]]);
    build(x<<1,l,mid),build(x<<1|1,mid+1,r);
    t[x].x=t[x<<1].x^t[x<<1|1].x;
}
void mdfy(int x,int p,int w){
    if (t[x].l==t[x].r) return void(t[x].x=w);
    mdfy(x<<1|(p>(t[x].l+t[x].r>>1)),p,w);
    t[x].x=t[x<<1].x^t[x<<1|1].x;
}
int srch(int x,int l,int r){
    if (t[x].l>r||t[x].r<l) return 0;
    if (t[x].l>=l&&t[x].r<=r) return t[x].x;
    return srch(x<<1,l,r)^srch(x<<1|1,l,r);
}
bool find(int x,int y){
    int ans=0;
    while (tp[x]!=tp[y]){
        if (dep[tp[x]]<dep[tp[y]]) swap(x,y);
        ans^=srch(1,id[tp[x]],id[x]),x=fa[tp[x]];
    }
    if (dep[x]<dep[y]) swap(x,y);
    return ans^srch(1,id[y],id[x]);
}
int main(){
    n=_read();
    for (int i=1;i<=n;i++) a[i]=_read();
    for (int i=1,x,y;i<n;i++)
        x=_read(),y=_read(),addedge(x,y),addedge(y,x);
    dfs1(1),tp[1]=1,dfs2(1),build(1,1,n),m=_read();
    for (int f,x,y;m;m--){
        f=_read(),x=_read(),y=_read();
        if (f=='Q') puts(find(x,y)?"Yes":"No");
        else mdfy(1,id[x],y);
    }
}

猜你喜欢

转载自blog.csdn.net/a1799342217/article/details/81740925
Nim
今日推荐