dingyeye loves stone
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 137 Accepted Submission(s): 82
dingyeye has an n-point tree.The nodes are numbered from 0 to n−1,while the root is numbered 0.Initially,there are a[i] stones on the i-th node.The game is in turns.When one move,he can choose a node and move some(this number cannot be 0) of the stones on it to its father.One loses the game if he can't do anything when he moves.
You always move first.You want to know whether you can win the game if you play optimally.
In each test case,the first line contains one integer n refers to the number of nodes.
The next line contains n−1 integers fa[1]⋯fa[n−1],which describe the father of nodes 1⋯n−1(node 0 is the root).It is guaranteed that 0≤fa[i]<i.
The next line contains n integers a[0]⋯a[n−1],which describe the initial stones on each nodes.It is guaranteed that 0≤a[i]<134217728.
1≤T≤100,1≤n≤100000.
It is guaranteed that there is at most 7 test cases such that n>100.
建一棵樹,每個節點有石子,每次可以移動石子到父節點,最後沒得移動的那個人輸,問先手能不能贏
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
/*
B 求每個點的深度.
設根節點的深度爲0,將所有深度爲奇數的節點的石子數目xor起來,
則先手必勝當且僅當這個xor和不爲0。
證明同階梯博弈。
對於偶深度的點上的石子,若對手移動它們,則可模仿操作;
對於奇深度上的石子,移動一次即進入偶深度的點。
時空複雜度O(n)。
*/
const int maxn = 1e5 + 5;
int fa[maxn];
int deep[maxn];
int stone[maxn];
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
memset(fa, 0, sizeof(fa));
memset(deep, 0, sizeof(deep));
int n;
scanf("%d", &n);
for (int i = 1; i < n; i++)
{
scanf("%d", &fa[i]);
deep[i] = deep[fa[i]]+1;
}
int ans = 0;
for (int i = 0; i < n; i++)
{
scanf("%d", &stone[i]);
if (deep[i] & 1) ans ^= stone[i];
}
if (ans != 0)
puts("win");
else puts("lose");
}
return 0;
}