魔法游戏 - 博弈论

题目大意:
给一颗树,每个位置有一个权值,每次一个人可以选择森林中的某棵树的根节点,设其权值为 a a a,那么这个人可以选择一个 k ∈ [ 2 , a + 1 ] k\in[2,a+1] k[2,a+1],然后让 a a a变成 ⌊ a k ⌋ \left\lfloor\frac ak\right\rfloor ka。如果一个点权值变为0那么就把这个点删除。不能操作者输,问谁赢。
题解:
考虑一个权值的二进制位,那么每次一个点的二进制位数会至少减1至多变成0。那么一颗树的sg就很好确定了。(其实直接暴力也可以不过没什么必要就直接写的简单了些。

#include<bits/stdc++.h>
#define R return
#define rep(i,a,b)for(_ i=a;i<=b;i++)
using namespace std;typedef int _;const _ N=100010;typedef unsigned long long ull;_ gc(){R getchar();}ull I(){ull x,c;while((c=gc())<'0'||c>'9');x=c^'0';while((c=gc())>='0'&&c<='9')x=x*10+c-'0';R x;}struct edges{_ T,P;}e[N<<1];_ h[N],E,s[N];_ A(_ u,_ v) {R e[++E].T=v,e[E].P=h[u],h[u]=E;}_ D(_ x,_ fa=0,_ t=0){for(_ i=h[x],y;i;i=e[i].P)if((y=e[i].T)^fa)t^=D(y,x);R s[x]-(s[x]<=t);}_ main(){for(_ n,x,y;scanf("%d",&n)!=EOF&&n;E=0,printf(D(1)?"Alice\n":"Marisa\n")){rep(i,1,n)s[i]=log2(I())+1,h[i]=0;rep(i,1,n-1)x=I()+1,y=I()+1,A(x,y),A(y,x);}R 0;}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值