ybtoj【数学基础】5章3题【魔法珠】

本文介绍了魔法珠的博弈游戏,重点讨论了有向图游戏中的SG函数和mex运算。通过解释SG函数的性质和SG定理,展示了如何解决这类问题。给出了直接计算SG值的暴力解法和构建SG值表的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

魔法珠

题目


解析

这道题需要一个知识:有向图游戏,SG函数与mex运算
我们先从有向图游戏讲起:
在一个DAG中,只有一个起点,上面有一个棋子,两个玩家轮流推动棋子,不能推动判负
mex:
mex就是不属于集合S的最小非负整数,即
m e x ( S ) = m i n x ∈ N , x ∉ S ( x ) mex(S)=min_{x∈N,x∉S}(x) mex(S)=minxN,x/S(x)
SG函数:
对于状态 x x x及其 k k k个后继状态 a 1 , a 2 . . . a k a_1,a_2...a_k a1,a2...ak,定义SG函数
S G ( x ) = m e x ( S G ( a 1 ) , S G ( a 2 ) . . . S G ( a k ) ) SG(x)=mex(SG(a_1),SG(a_2)...SG(a_k)) SG(x)=mex(SG(a1),SG(a2)...SG(ak))
性质:
1,最终状态SG=0
2,必胜状态SG≠0必有一个后继状态SG=0
3,必败状态SG=0必无后继状态SG=0
SG定理:
对于由 n n n个有向图游戏组成的组合游戏,设它们的起点分别是 s 1 , s 2 , . . . , s n s_1,s_2,...,s_n s1,s2,...,sn,则
当且仅当 S G ( s 1 )    x o r    S G ( s 2 )    x o r    . . .    x o r    S G ( s n ) ≠ 0 SG(s_1)\;xor\;SG(s_2)\;xor\;...\;xor\;SG(s_n)≠0 SG(s1)xorSG(s2)xor...xorSG(sn)=0时,先手必胜
证明:
1,最终局面显然成立
2,对于任意情况,显然可以取到该数-1,不能取到原数(否则等同于没取),也就是NIM游戏
对于这道题,显然直接暴力SG即可
当然也可以打表写出SG值

code:

#include<cstdio>
#include<cstring>
using namespace std;
int n,x,sg[1010],ans;
inline int SG(int x)
{
	if(sg[x]!=-1)return sg[x];
	int y=0;
	for(int i=1;i*i<=x;++i)if(!(x%i)){if(i!=x)y^=SG(i);if(i*i!=x&&i!=1)y^=SG(x/i);}
	bool ch[1010];memset(ch,0,sizeof(ch));
	for(int i=1;i*i<=x;++i)if(!(x%i)){if(i!=x)ch[SG(i)^y]=1;if(i*i!=x&&i!=1)ch[SG(x/i)^y]=1;}
	while(ch[++sg[x]]);
	return sg[x];
}
int main()
{
	for(int i=1;i<=1000;++i)sg[i]=-1;
	while(scanf("%d",&n)!=EOF)
	{
		ans=0;
		while(n--)scanf("%d",&x),ans^=SG(x);
		printf(ans?("freda\n"):("rainbow\n"));
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值