1. 程式人生 > >【HDOJ5996】dingyeye loves stone(Nim遊戲)

【HDOJ5996】dingyeye loves stone(Nim遊戲)

題意:dingyeye喜歡和你玩石子游戲。dingyeye有一棵n個節點的有根樹,節點編號為0到n−1,根為0號節點。

遊戲開始時,第i個節點上有a[i]個石子。兩位玩家輪流操作,每次操作玩家可以選擇一個節點,並將該節點上的一些石子(個數不能為0)移動到它的父親節點上去。

如果輪到某位玩家時,該玩家沒有任何合法的操作可以執行,則判負。你在遊戲中執先手,你想知道當前局面你能否必勝。

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

思路:

設根節點的深度為00,將所有深度為奇數的節點的石子數目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\n"); 38 else printf("lose\n"); 39 } 40 return 0; 41 } 42