CF850C

学习 SG 基础题。

首先发现每个质数之间是独立的,于是分成了若干个子游戏。

考虑如何计算每个子游戏的 SG 值。一开始没搞懂为什么可以状压,看了大佬代码才明白:对于一个质数 ppk 对答案是否有影响,只和这个 k 是否出现有关。所以将 k 的出现状态情况成二进制数 u,则它的所有后继状态 v 可以表示为 (u>>k)|(((1<<(k1))1)&u),其中 k 为该次选择 pk。然后直接套用 SG 函数的计算方式即可。

计算出每个子游戏的 SG 值,最后套用 SG 定理即可。

注意到不同质数,状态相同,得到答案也相同。使用记忆化优化时间复杂度。具体复杂度我也不会算啊。

code:

点击查看代码
int n,m;
map<int,int> mp,f;//数据范围较大,使用 map
int calc(int u){
	if(!u)
		return 0;
	if(mp.count(u))
		return mp[u];
	set<int> st;
	for(int i=1;i<=30;i++){
		int v=(u>>i)|(((1<<(i-1))-1)&u);
		if(v==u)
			break;
		st.insert(calc(v));
	}
	for(int i=0;i<=100;i++){
		if(!st.count(i))
			return mp[u]=i;
	}//SG 函数取 mex
}
void solve(){
	scanf("%d",&n);
	for(int i=1,x;i<=n;i++){
		scanf("%d",&x);
		for(int j=2;j*j<=x;j++){
			int cnt=0;
			while(x%j==0)
				x/=j,cnt++;
			if(cnt>0)
				f[j]|=1<<(cnt-1);
		}
		if(x>1)
			f[x]|=1;
	}//质因数分解
	int ans=0;
	for(auto i=f.begin();i!=f.end();i++)
		ans^=calc(i->second);//SG 定理
	if(!ans)
		puts("Arpa");
	else
		puts("Mojtaba");
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)solve();
}
posted @   yinhee  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示