这个题感觉就是头脑风暴吧,关键在于抓住正确的方向想下去,我中间也跑偏了几次。。。
定义一个分支为从叶子往根的方向,不存在包含多个子节点的节点序列,即从叶子到包含多个子节点的节点的前一个节点的节点序列。(当然这个分支的定义不是一开始就想到的,而是在慢慢深入思考过程中完善的,先写这个只是为了便于叙述)
首先最重要的一点,可以说是走向正确思路的第一步,如果存在只有一个节点的分支,那么先手必胜。
语言上的证明如下,假设初始局面是去掉其中一个只有一个节点的分支以后的局面:如果该局面是先手必胜的,则说明先手可以到达某个先手必败的局面,而加上一个只有一个节点的分支不影响先手到达原来能到的局面,因此先手必胜;如果该局面是先手必败 的,那么先手可以通过只取这个一个节点的分支到达该局面。因此,如果存在只有一个节点的分支,那么先手必胜。
考虑到这个以后,就可以继续思考。如果不存在只有一个节点的分支,对于两个节点的分支,显然没有人愿意取该分支,因为取了之后就会变成先手必胜的局面,显然如果所有分支节点数都为2,则先手必败。那么可以发现节点数为2的分支其实和0是等价的,因为根本就不会被人取,也就不影响局面。
那么思考3的时候,就会发现,这不就又变成了1的情况,如果把其中一个3的分支先变成2,再通过上述证明存在只有一个节点分支的方法来证明,所以如果存在只有三个节点的分支,则先手必胜。那么4分支和2分支又等价。。。
由上述过程,显然可以归纳一下,只有所有分支全为偶数的时候先手必败,否则必胜。
(PS:我想这题的时候,在思考分支的定义时走了不少弯路QAQ,导致一开始就想到了第一步,但是还是想了一段时间才想到后面的)
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+5;
int t,n,sz[maxn],fa[maxn];
int main(){
//freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(sz,0,(n+5)*sizeof(int));
for(int i=2;i<=n;i++){
scanf("%d",&fa[i]);
sz[fa[i]]++;
}
bool f=0;
for(int i=1;i<=n&&!f;i++){
if(sz[i]==0){
int u=i,tt=0;
while(sz[u]<2){
tt++;
if(u==1)break;
u=fa[u];
}
if(tt&1) f=1;
}
}
if(f) puts("Takeru");
else puts("Meiya");
}
return 0;
}