這個題感覺就是頭腦風暴吧,關鍵在於抓住正確的方向想下去,我中間也跑偏了幾次。。。
定義一個分支爲從葉子往根的方向,不存在包含多個子節點的節點序列,即從葉子到包含多個子節點的節點的前一個節點的節點序列。(當然這個分支的定義不是一開始就想到的,而是在慢慢深入思考過程中完善的,先寫這個只是爲了便於敘述)
首先最重要的一點,可以說是走向正確思路的第一步,如果存在只有一個節點的分支,那麼先手必勝。
語言上的證明如下,假設初始局面是去掉其中一個只有一個節點的分支以後的局面:如果該局面是先手必勝的,則說明先手可以到達某個先手必敗的局面,而加上一個只有一個節點的分支不影響先手到達原來能到的局面,因此先手必勝;如果該局面是先手必敗 的,那麼先手可以通過只取這個一個節點的分支到達該局面。因此,如果存在只有一個節點的分支,那麼先手必勝。
考慮到這個以後,就可以繼續思考。如果不存在只有一個節點的分支,對於兩個節點的分支,顯然沒有人願意取該分支,因爲取了之後就會變成先手必勝的局面,顯然如果所有分支節點數都爲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;
}