题意:有一颗n个节点的树,1号点为根节点,其他点上分别放有若干个石子,两个人轮流操作,每次可以将某个节点上的若干个石子移动到这个节点的父亲上面,无法操作者负,问先手是否必胜。
以0(root)为的深度为1,我们首先发现,0作为root,它上面的石子不管有多少对结果都无法造成影响,故可以视为0,再考察深度为奇数的节点,如果这上面有石子,那么不管alice从这里拿多少石子移到父亲节点上,bob都可以模仿alice的操作,这样的话,这些石子又将放到深度为奇数的节点上,直到root,因此直到所有奇数深度都到root,alice无法操作了,就必败了。因此我们可以把奇数节点都视作0,即消失了,因为对答案没有贡献。
因为偶数层石子谁最后取完,谁就赢得了游戏,这样问题变转化为偶数层的石子做nim游戏。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int n;
int deep[maxn];
int a[maxn];
vector<int> son[maxn];
void dfs(int x, int d)
{
deep[x] = d;
for(auto it : son[x]) {
dfs(it, d+1);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(deep, 0,sizeof(deep));
scanf("%d",&n);
for(int i = 0; i< n; i++) son[i].clear();
for(int i = 1; i <= n-1; i++){
int f;
scanf("%d",&f);
son[f].push_back(i);
}
for(int i = 0; i < n; i++){
scanf("%d",&a[i]);
}
dfs(0,1);
int nim = 0;
for(int i = 1; i< n; i++){
if(deep[i] % 2 == 0){
nim ^= a[i];
}
}
if(nim == 0){
printf("lose\n");
}
else{
printf("win\n");
}
}
} 
京公网安备 11010502036488号