20170908 校内模拟赛 游戏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20170908 校内模拟赛 游戏相关的知识,希望对你有一定的参考价值。

T1.游戏(game)
小 z 和小 Z 最近迷上了玩 Nim 游戏,这个游戏的规则是这样的:有 n 堆石
子,第 i 堆有 ai 个石子。两个人轮流操作,每次可以任意取一堆的任意多个石
子,可以取完或者不取完,谁先取不了谁输。
每次创造一个初始局面过于麻烦, 他们决定把石子聚成很多堆, 又把这些堆
摆成一棵树,每次选择一条链上的所有石子堆作为初始局面玩游戏。当然,他们
还经常修改石子堆里的石子数量。
小 Z 明白这个游戏是有必胜策略的,所以他总是按照策略行动,并且经常
获胜。小 z 并不知道获胜策略,所以他去请教了机智的小 d。在明白了获胜策略
之后他恍然大悟, 这时他回想起了和小 Z 玩的好多场游戏, 他想知道其中有哪些
游戏他一定会失败?
由于小 Z 好强,所以小 z 总是后手。

#include<cstdio>
struct edge{
    int to,nx;
}e[5000001];
int h[500001];
int n,Q,p;
int num;
int a[500001];
int fa[500001][21],dep[500001],l[500001],r[500001];
int BIT[500001];
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==0)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
void update(int x,int v){
    for(int i=x;i<=n;i+=(i&(-i))){
        BIT[i]^=v;
    }
}
int query(int x){
    int ans=0;
    for(int i=x;i;i-=(i&(-i))){
        ans^=BIT[i];
    }
    return ans;
}
void ae(int fr,int to){
    e[++p]=(edge){to,h[fr]};h[fr]=p;
}
void dfs(int x){
    for(int i=1;i<=20;i++){
        if(dep[x]>=(1<<i)){
            fa[x][i]=fa[fa[x][i-1]][i-1];
        }
        else break;
    }
    l[x]=++num;
    for(int i=h[x];i;i=e[i].nx){
        int v=e[i].to;
        if(v!=fa[x][0]){
            dep[v]=dep[x]+1;
            fa[v][0]=x;
            dfs(v);
        }
    }
    r[x]=num;
}
int lca(int x,int y){
    if(dep[x]<dep[y]){
        int tm=x;x=y;y=tm;
    }
    int t=dep[x]-dep[y];
    for(int i=0;i<=20;i++){
        if((1<<i)&t) x=fa[x][i];
    }
    for(int i=20;i>=0;i--){
        if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
    }
    if(x==y) return x;
    return fa[x][0];
}
int main(){
    //freopen("game.in","r",stdin);
    //freopen("game.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    for(int i=1;i<n;i++){
        int x=read(),y=read();
        ae(x,y);ae(y,x);
    }
    dfs(1);
    for(int i=1;i<=n;i++){
        update(l[i],a[i]);update(r[i]+1,a[i]);
    }
    Q=read();
    while(Q--){
        char op[5];
        scanf("%s",op);
        int x=read(),y=read();
        if(op[0]==Q){
            int LCA=lca(x,y);
            int sg=query(l[x])^query(l[y])^a[LCA];
            if(sg) puts("Yes");
            else puts("No");
        }
        else{
            update(l[x],a[x]);update(r[x]+1,a[x]);
            a[x]=y;
            update(l[x],y);update(r[x]+1,y);
        }
    }
    return 0;
}

 

以上是关于20170908 校内模拟赛 游戏的主要内容,如果未能解决你的问题,请参考以下文章

校内模拟测试010T1 删点游戏dt

9.10 AHSOFNU校内模拟

例行报告(20170908-20170910)

校内模拟赛T1大美江湖

校内模拟赛 虫洞(by NiroBC)

2017-9-3 校内模拟T2取数win