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)。

接着看并联情况:

这就是几个互不影响的游戏的组合,用SG定理,把SG值异或起来即可。

重点来了!串联的情况!

http://blog.csdn.net/longshuai0821/article/details/7793043 贴个阶梯博弈先

先不看四号和五号。如果在二号先手就必胜了,那么对手肯定不会甘于在二号点移动而是跑去三号点试图改变局面,但这是徒劳的:我可以把他移过来2号点的东西全部丢到一号点,从而毫不影响先手胜的局面,也就是三号对答案毫无影响。现在看四不看五,由于三号对答案无影响,四号应该发挥积极作用,也就是如果从四号拿了一些到三号,是会影响结果的,这等价于从四号点拿了一些石头丢掉了!因为三号点是没用点,有多少石头都无所谓!也就是说四号点和二号点两个互不影响地构成了这个游戏且规则相同。最后看五号点,如果对手把五号点丢给四号,那么我也可以把丢到四号的那些石头丢给三号。

综上,与根距离为偶数的点都是废点。所以只需要记录并更新距离是奇数的点SG值即可。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<stdlib.h>
 5 #include<iostream>
 6 using namespace std;
 7
 8 int n,t,m;
 9 #define maxn 10011
10 struct Edge{int to,next;}edge[maxn<<1];int first[maxn],le=2;
11 void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;}
12 void insert(int x,int y) {in(x,y);in(y,x);}
13 int val[maxn],dep[maxn],ans;
14 void dfs(int x,int fa)
15 {
16     dep[x]=dep[fa]+1;
17     if (dep[x]&1) ans^=val[x];
18     for (int i=first[x];i;i=edge[i].next)
19     {
20         const Edge &e=edge[i];if (e.to==fa) continue;
21         dfs(e.to,x);
22     }
23 }
24 int calc(int x) {return x%(m+1);}
25 int main()
26 {
27     scanf("%d%d%d",&n,&t,&m);
28     int x,y;
29     for (int i=2;i<=n;i++)
30     {
31         scanf("%d%d",&x,&y);
32         insert(x,i);
33         val[i]=calc(y);
34     }
35     dep[0]=-1;ans=0;dfs(1,0);
36     for (int i=1;i<=t;i++)
37     {
38         scanf("%d%d",&x,&y);
39         if (dep[x]&1)
40         {
41             ans^=val[x];
42             val[x]=calc(y);
43             ans^=val[x];
44         }
45         printf(ans?"Yes\n":"No\n");
46     }
47     return 0;
48 }

时间: 2024-10-27 04:05:45

BZOJ1777: [Usaco2010 Hol]rocks 石头木头的相关文章

【博弈论】【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]=firs

BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡

1778: [Usaco2010 Hol]Dotp 驱逐猪猡 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 563  Solved: 216[Submit][Status][Discuss] Description 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<

bzoj1776[Usaco2010 Hol]cowpol 奶牛政坛*

bzoj1776[Usaco2010 Hol]cowpol 奶牛政坛 题意: 给出一个树,每个节点k个政党中的一个.问每个政党间最远的两个节点距离多少.节点数≤200000. 题解: 有个结论:每个政党所求两个节点其中一个必然是这个政党中深度最大的节点.因此枚举每个节点,计算该节点与节点所属政党深度最大节点的距离(倍增法),与给政党的答案比较即可. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorit

BZOJ1778 [Usaco2010 Hol]Dotp 驱逐猪猡

首先我们列出转移矩阵$M$,$M_{i, j} = \frac {1 - \frac{p} {q}} {deg[i]}$(i,j之间有边)or $M_{i, j} = 0$(i,j之间没边) 则这个矩阵$M_{i, j}$表示的是站在某个点$i$,下一次走到$j$且没有爆炸的概率 我们再看$M^n_{i, j}$,表示的站在某个点$i$,走$n$步以后到达$j$且没有爆炸的概率 故$M^n$的第一列代表了$1$号点到其他所有点的概率,设为列向量$A_n$,则$A_n = M^n * B$,其中$

【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接.保证城市1至少连接一个其它的城市.一开始臭气弹会被放在城市1.每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <

BZOJ 1778 Usaco2010 Hol Dotp 驱逐猪猡 期望DP+高斯消元

题目大意:给定一个无向图,炸弹从1号节点出发,每个时刻有P/Q的概率爆炸,如果某个时刻没有爆炸,就会等概率沿着随机一条出边走到下一个城市,求最终每个城市的爆炸概率 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 330 using namespace std; int n,m,p,q;

COGS——T 803. [USACO Hol10] 政党 || 1776: [Usaco2010 Hol]cowpol 奶牛政坛

http://www.lydsy.com/JudgeOnline/problem.php?id=1776||http://cogs.pro/cogs/problem/problem.php?pid=803 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 507  Solved: 246[Submit][Status][Discuss] Description 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.

【BZOJ】1778: [Usaco2010 Hol]Dotp 驱逐猪猡

[题意]给定无向图,炸弹开始在1,在每个点爆炸概率p/q,不爆炸则等概率往邻点走,求在每个点爆炸的概率. [算法]数学概率期望+高斯消元 [题解]令f[i]表示炸弹到达i点的概率(之前不爆炸). f[i]=∑f[j]*(1-Q)/d[j] 特别的,f[1]=∑f[j]*(1-Q)/d[j]+1(一开始就到达). 只要一个点到就是到达,故使用概率加法. 使用高斯消元求解方程组,最后ansi=f[i]*Q. 另一种思路,由于炸弹最终爆炸概率为1,所以sum=∑f[i],ansi=f[i]/sum 此

BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元

题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接.保证城市1至少连接一个其它的城市.一开始臭气弹会被放在城市1.每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <