dingyeye loves stone

dingyeye loves stone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 82    Accepted Submission(s): 48


dingyeye喜欢和你玩石子游戏。

dingyeye有一棵nn个节点的有根树,节点编号为00n-1n1,根为00号节点。游戏开始时,第ii个节点上有a[i]a[i]个石子。两位玩家轮流操作,每次操作玩家可以选择一个节点,并将该节点上的一些石子(个数不能为00)移动到它的父亲节点上去。如果轮到某位玩家时,该玩家没有任何合法的操作可以执行,则判负。

你在游戏中执先手,你想知道当前局面你能否必胜。
输入描述
本题有多组数据,第一行为一个非负整数TT,表示数据组数。

对于每组数据,第一行一个整数nn,表示节点数目。

接下来一行为n-1n1个整数fa[1]\cdots fa[n-1]fa[1]fa[n1],分别描述了除根节点外每个点的父亲。方便起见,保证$0\leq fa[i]\< i$。

接下来一行为nn个非负整数a[0]\cdots a[n-1]a[0]a[n1],分别描述了每个点初始的石子数。保证0\leq a[i]<1342177280a[i]<1342177281\leq T\leq 1001T1001\leq n\leq 1000001n100000。

保证n>100n>100的测试点数目不超过77个。
输出描
Sample Input
  
  
2 2 0 1000 1 4 0 1 0 2 3 3 3
 

Sample Output
  
  
win lose
思路:设根节点的深度为00,将所有深度为奇数的节点的石子数目 xor 起来,则先手必胜当且仅当这个 xor 和不为0。 证明同阶梯博弈。对于偶深度的点上的石子,若对手移动它们,则可模仿操作;对于奇深度上的石子,移动一次即进入偶深度的点。 时间复杂度 O(n)。
分析:其实就是个n堆的尼姆博弈。因为是一棵树,所以是分层次的,而且都是连起来的。那么先手当然希望是把1,3,5,7....奇数层的都清空,这样就可以使后手无法满足题目中"并将该节点上的一些石子移动到它的父亲节点上去",因为层与层都割断了嘛。至于为什么是奇数层,是因为把根节点当做第0层,因为根节点不能移动。
体会:思路还是很清晰的,就是不知道如何处理把奇数层给选出来,当时还用了vector把属于同一根节点的儿子都加进来,其实还是在层次的处理上还是不正确的....
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int fa[100010];
int depth[100010];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(fa,0,sizeof(fa));
		scanf("%d",&n);
		for(int i=1;i<n;i++)
		{
			scanf("%d",&fa[i]);
			depth[i]=depth[fa[i]]+1;
		
		}
		int ans=0;
		for(int i=0;i<n;i++)
		{
			int x;
			scanf("%d",&x);
			if(depth[i]&1)
            {
                ans=ans^x;
                
            }

		}

		if(ans)
			puts("win");
		else
			puts("lose");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值