【题解】玲珑学院oj1087 Alice and Bob

题目链接

题意:给定一棵满二叉树,每个点有一个权值。两人轮流操作,每次操作可以选一个点u,将点u的权值减小x,0<x≤au(点u的权值),若点u不是叶子节点,则再选择u的一个儿子v,将v的权值加上x。不能操作者输。问先手有多少种必胜策略。

分析:将叶子节点所在的层定义为第1层,向上层数递增。

        记sg为奇数层节点权值的异或和。则先手必胜当且仅当sg≠0。

        证明思路:1.sg≠0的状态可经过一次操作到达sg=0的状态。

                            2.sg=0的状态经过一次操作必到达sg≠0的状态。

        从而先手的必胜策略即第一步把sg变成0的操作种数。若选取的是奇数层节点u,则当sg^au∈[0,au)时可以取x=au-sg^au。若选取的是偶数层节点u,设u的左、右儿子分别为l、r,则当sg^al∈(al,al+au]时可以取x=sg^al-al将其加到节点l的权值,对r同理。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<21;
int n,a[maxn];
int main()
{
	int T;cin>>T;
	while (T--)
	{
		scanf("%d",&n);
		int k=0,sg=0,ans=0;
		for (int i=0;i<n;i++)
		    for (int j=1;j<=(1<<i);j++)
		    {
		    	k++;scanf("%d",&a[k]);
				if ((n-1-i)%2==0) sg^=a[k];
			}
		k=0;
		for (int i=0;i<n;i++)
		    for (int j=1;j<=(1<<i);j++)
		    {
		    	k++;
		    	if ((n-1-i)%2==0)
		    	{
		    		if ((sg^a[k])>=a[k]) continue;
		    		if (i==n-1) ans++;
		    		else ans+=2;
				}
				else
				{
					int sg1=sg^a[2*k],sg2=sg^a[2*k+1];
					if (sg1>a[2*k]&&sg1<=a[2*k]+a[k]) ans++;
					if (sg2>a[2*k+1]&&sg2<=a[2*k+1]+a[k]) ans++;
				}
			}
		printf("%d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值