zoukankan      html  css  js  c++  java
  • 「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;
    }
    
    
    
  • 相关阅读:
    C++中虚继承的作用
    游戏程序设计学习初窥简单DirectX代码实现
    vue4.x更改默认端口 larry
    Visual studio 2010几个比较酷的功能
    Web前端编程:勿混淆NodeList与Array
    代码规范之署名
    一则中文文件名引起的问题
    C# WebService调用及数据并行处理
    2010年终总结
    关于DotNetNuke
  • 原文地址:https://www.cnblogs.com/lizbaka/p/10246414.html
Copyright © 2011-2022 走看看