【博弈论】【SG函数】bzoj1777 [Usaco2010 Hol]rocks 石头木头

仅有距根节点为奇数距离的节点的石子被移走对答案有贡献,∵即使偶数的石子被移走,迟早会被再移到奇数,而奇数被移走后,不一定能够在移到偶数(到根了)。

最多移L个:石子数模(L+1),比较显然,也可以自己跑一跑奇数层的SG函数。

#include<cstdio>
using namespace std;
#define N 10001
int en,v[N],first[N],next[N];
void AddEdge(int U,int V)
{
	v[++en]=V;
	next[en]=first[U];
	first[U]=en;
}
int n,q,m,a[N],ans;
void dfs(int U,int d)
{
	if(d&1) ans^=a[U];
	for(int i=first[U];i;i=next[i])
	  dfs(v[i],d+1);
}
int main()
{
	int A,B;
	scanf("%d%d%d",&n,&q,&m);
	for(int i=2;i<=n;++i)
	  {
	  	scanf("%d%d",&A,&a[i]);
	  	a[i]%=(m+1);
	  	AddEdge(A,i);
	  }
	for(;q;--q)
	  {
	  	scanf("%d%d",&A,&B);
	  	a[A]=B%(m+1);
	  	ans=0;
	  	dfs(1,0);
	  	puts(ans?"Yes":"No");
	  }
	return 0;
}
时间: 2024-11-03 22:29:49

【博弈论】【SG函数】bzoj1777 [Usaco2010 Hol]rocks 石头木头的相关文章

BZOJ1777: [Usaco2010 Hol]rocks 石头木头

n<=10000的树,节点有初始石头数<=1000,进行这样的游戏:两人轮流行动,我先手,每次可以选一个节点(≠1)把不超过m<=1000个石头移到父亲,最后所有石头都在节点1,没法行动的算输.有T<=10000次修改操作,把某点初始石头数修改,求每次修改后能否先手胜. 突然发现博弈全忘光了.. 首先看: 最简单的一种情况,可以用SG函数表示二号点的情况.可以打表或手推或显然得出SG值:0 1 2 -- m 0 1 2 -- m -- SG(i)=i%(m+1). 接着看并联情况:

[BZOJ 1874] [BeiJing2009 WinterCamp] 取石子游戏 【博弈论 | SG函数】

题目链接:BZOJ - 1874 题目分析 这个是一种组合游戏,是许多单个SG游戏的和. 就是指,总的游戏由许多单个SG游戏组合而成,每个SG游戏(也就是每一堆石子)之间互不干扰,每次从所有的单个游戏中选一个进行决策,如果所有单个游戏都无法决策,游戏失败. 有一个结论,SG(A + B + C ... ) = SG(A)^SG(B)^SG(C) ... 这道题每堆石子不超过 1000 , 所以可以把 [0, 1000] 的 SG 值暴力求出来,使用最原始的 SG 函数的定义, SG(u) = m

博弈论SG函数

SG(x)=mex(S),S是x的后继状态的SG函数集合,mex(S)表示不在S内的最小非负整数.如果为0就是必败状态,否则就是必胜状态. 这道题目和Nim差不多,一共有两群熊猫,依次分析,最后异或即可. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<queue&g

博弈论-sg函数

今天A了张子苏大神的sg函数的题,感觉神清气爽. 一篇对于sg函数讲的很透彻的博文:http://acm.hdu.edu.cn/forum/read.php?fid=9&tid=10617 我来整理一下: 问题1:今有若干堆火柴,两人依次从中拿取,规定每次只能从一堆中取若干根, 可将一堆全取走,但不可不取,最后取完者为胜,求必胜的方法.  定义:若所有火柴数异或为0,则该状态被称为利他态,用字母T表示:否则, 为利己态,用S表示. 注意:这篇博文是先定义s和t,再通过它们的性质推出结论. [定理

[BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】

题目链接:BZOJ - 1188 题目分析 我们把每一颗石子看做一个单个的游戏,它的 SG 值取决于它的位置. 对于一颗在 i 位置的石子,根据游戏规则,它的后继状态就是枚举符合条件的 j, k.然后后继状态就是 j 与 k 这两个游戏的和. 游戏的和的 SG 值就是几个单一游戏的 SG 值的异或和. 那么还是根据 SG 函数的定义 , 即 SG(u) = mex(SG(v)) ,预处理求出每个位置的 SG 值.一个位置的 SG 值与它后面的位置有关,是取决于它是倒数第几个位置,那么我们预处理求

2016多校联合训练1 B题Chess (博弈论 SG函数)

题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外,不能移动了就算输,两个人都用最优策略,问先手是否有必胜策略. 这题显然就是SG函数了吧.行与行之间互不影响,所以可以看成n个子游戏,求出它们各自的SG函数然后异或一下就可以了.我们发现只有20列,2^21=2097152,所以我们可以先把行的所有情况的SG函数预处理出来,然后每次询问O(1)就行了. 代

ZOJ 3057 Beans Game 博弈论 sg函数

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3057 典型的sg函数,数据范围卡得真好啊 代码 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 #include<map> 7 using namespac

POJ 2425 A Chess Game 博弈论 sg函数

http://poj.org/problem?id=2425 典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和.仍然是因为看不懂题目卡了好久. 这道题大概有两个坑, 1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了): 2.是n个点的有向无环图边数上限是n^2(re了好久QAQ). 在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快.下一篇大概会写一个小结. 代码 1 #include<cstdio> 2 #inclu

POJ 2960 S-Nim 博弈论 sg函数

http://poj.org/problem?id=2960 sg函数几乎是模板题. 调试代码的最大障碍仍然是手残在循环里打错变量名,是时候换个hydra产的机械臂了[超想要.jpg] 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 #include<map> 7 using na