(2016北京集訓十三)【xsy1531】魔法遊戲 - Nim遊戲

題解:

好題!個人結論很接近正解了。。。ios

把一個數化成二進制,每次至少要拿走一位,最多全拿走,不能不拿。那麼這就是一個經典的Nim問題了,子樹異或起來就是根節點的答案,隨便遞推一下就好了。spa

代碼:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<queue>
 7 #define inf 2147483647
 8 #define eps 1e-9
 9 using namespace std; 10 typedef unsigned long long ll; 11 struct edge{ 12     int v,next; 13 }a[200001]; 14 int n,u,v,tot=0,num[100001],head[100001]; 15 ll x; 16 void add(int u,int v){ 17     a[++tot].v=v; 18     a[tot].next=head[u]; 19     head[u]=tot; 20 } 21 int dfs(int u,int fa){ 22     int ret=num[u],tp=0; 23     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){ 24         int v=a[tmp].v; 25         if(v!=fa)tp^=dfs(v,u); 26  } 27     if(ret<=tp)ret--; 28     return ret; 29 } 30 int main(){ 31     while(scanf("%d",&n)==1){ 32         memset(head,-1,sizeof(head)); 33         tot=0; 34         for(int i=1;i<=n;i++){ 35             //scanf("%lld",&x);
36             cin>>x; 37             num[i]=(int)log2(x)+1; 38  } 39         for(int i=1;i<n;i++){ 40             scanf("%d%d",&u,&v); 41             add(u+1,v+1); 42             add(v+1,u+1); 43  } 44         if(dfs(1,-1))printf("Alice\n"); 45         else printf("Marisa\n"); 46  } 47     return 0; 48 }

 ps:NOIp2018模擬賽三十九不想寫,不寫了code

相關文章
相關標籤/搜索