题意: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