【HDOJ5996】dingyeye loves stone(Nim游戏)

题意:dingyeye喜欢和你玩石子游戏。dingyeye有一棵n个节点的有根树,节点编号为0到n−1,根为0号节点。

游戏开始时,第i个节点上有a[i]个石子。两位玩家轮流操作,每次操作玩家可以选择一个节点,并将该节点上的一些石子(个数不能为0)移动到它的父亲节点上去。

如果轮到某位玩家时,该玩家没有任何合法的操作可以执行,则判负。你在游戏中执先手,你想知道当前局面你能否必胜。

n<=1e5,0<=a[i]<=134217728

思路:

设根节点的深度为0,将所有深度为奇数的节点的石子数目xor起来,则先手必胜当且仅当这个xor和不为0。 证明同阶梯博弈。

对于偶深度的点上的石子,若对手移动它们,则可模仿操作;对于奇深度上的石子,移动一次即进入偶深度的点。 时空复杂度O(n)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 typedef long long ll;
 7 using namespace std;
 8 #define N   110000
 9 #define oo  10000000
10 #define MOD 1000000007
11 
12 int dep[N];
13 
14 int main()
15 { 
16     int cas;
17     scanf("%d",&cas);
18     while(cas--)
19     {
20         int n;
21         scanf("%d",&n);
22         dep[1]=0;
23         for(int i=2;i<=n;i++)
24         {
25             int x;
26             scanf("%d",&x);
27             x++;
28             dep[i]=dep[x]+1;
29         }
30         int ans=0;
31         for(int i=1;i<=n;i++)
32         {
33             int x;
34             scanf("%d",&x);
35             if(dep[i]&1) ans^=x;
36         }
37         if(ans) printf("win
");
38          else printf("lose
");
39     } 
40     return 0;
41 }
42     
原文地址:https://www.cnblogs.com/myx12345/p/9958803.html