• 「Luogu2972」 [USACO10HOL]岩石和树木Rocks and Trees


    关于Nim游戏,sg函数及其一些变形可以戳这位大佬的blog:

    https://blog.csdn.net/clover_hxy/article/details/53818624


    problem

    Solution

    这是一道阶梯Nim游戏的题,与普通的阶梯Nim游戏不同之处在于它是在一棵树上移动,实际上就是多个阶梯Nim游戏的复合

    我们知道,阶梯Nim游戏可以视作对奇数阶梯上上的石子做Nim,证明在上方的blog中有提及,在此不再赘述

    在此题中,设(1)号节点的深度为(0),那么深度为奇数的节点即为“奇数阶梯”

    考虑每次对节点上石头数量的修改,我们可以保存上一次修改后求出的(sg)值的异或和(x)

    如果修改的节点的深度为偶数,对答案并没有贡献,直接判断上一次的(x)即可

    如果修改的节点的深度为奇数,由于异或满足自反性(即(x) xor (x) (=0)),所以在修改之前,我们只需要对(x)异或一遍修改前的数,再异或一遍修改后的数即可,而没有必要重新求一遍异或和

    Code

    #include <cstdio>
    #define maxn 10005
    #define maxL 1005
    using namespace std;
    
    int n,T,L;
    int r[maxn],prt[maxn],dep[maxn];
    int sg[maxL];
    
    int x;
    inline bool Solve(int pos,int chg)
    {
        if(!(dep[pos]&1))
            return x;
        x^=sg[r[pos]];
        x^=sg[r[pos]=chg];
        return x;
    }
    
    int main()
    {
        scanf("%d%d%d",&n,&T,&L);
        register int i;
        int a,b;
        for(i=1;i<=1000;++i)
            sg[i]=i%(L+1);
        for(i=2;i<=n;++i)
        {
            scanf("%d%d",&prt[i],&r[i]);
            dep[i]=dep[prt[i]]+1;
            if(dep[i]&1)
                x^=sg[r[i]];
        }
        for(i=1;i<=T;++i)
        {
            scanf("%d%d",&a,&b);
            if(Solve(a,b))
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    【论文阅读】A practical algorithm for distributed clustering and outlier detection
    第11组 团队Git现场编程实战
    第11组 团队项目-需求分析报告
    团队项目-选题报告
    第二次结对编程作业
    第11组 团队展示
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    (转)script标签到底该放在哪里
  • 原文地址:https://www.cnblogs.com/lizbaka/p/10246414.html
Copyright © 2020-2023  润新知