1 条题解
-
0
自动搬运
来自洛谷,原作者为

lizbaka
「道阻且长,行而未至」搬运于
2025-08-24 21:43:58,当前版本为作者最后更新于2018-08-29 22:23:08,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
关于Nim游戏,sg函数及其一些变形可以戳这位大佬的blog:
https://blog.csdn.net/clover_hxy/article/details/53818624
Solution
这是一道阶梯Nim游戏的题,与普通的阶梯Nim游戏不同之处在于它是在一棵树上移动,实际上就是多个阶梯Nim游戏的复合
我们知道,阶梯Nim游戏可以视作对奇数阶梯上上的石子做Nim,证明在上方的blog中有提及,在此不再赘述
在此题中,设号节点的深度为,那么深度为奇数的节点即为“奇数阶梯”
考虑每次对节点上石头数量的修改,我们可以保存上一次修改后求出的值的异或和
如果修改的节点的深度为偶数,对答案并没有贡献,直接判断上一次的即可
如果修改的节点的深度为奇数,由于异或满足自反性(即 xor ),所以在修改之前,我们只需要对异或一遍修改前的数,再异或一遍修改后的数即可,而没有必要重新求一遍异或和
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\n"); else printf("No\n"); } return 0; }
- 1
信息
- ID
- 2037
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者