ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【BZOJ2410】Nim游戏(博弈论)

2021-07-23 14:33:23  阅读:191  来源: 互联网

标签:颜色 格子 Nim SG1 BZOJ2410 博弈论 限制 SG define


点此看题面

  • 有\(n\)个格子,初始有一部分被染上了颜色。
  • 两人轮流从\(k\)种颜色中选择一种给某个未被染色的格子染上颜色,要求不能有相邻格子被染上了相同颜色。
  • 要求判断先手是否有必胜策略。
  • \(n\le10^5\)

\(k\ge3\)的情况

如果\(k\ge 3\),每个格子必然都能被染上颜色。

因此胜负情况只取决于未被染色的格子数的奇偶性,即当且仅当未被染色的格子数为奇数时先手胜。

\(k=1\)的情况

设\(SG1(n)\)表示\(k=1\)时在\(n\)个空格子中博弈的\(SG\)函数。

一种情况是选择了边上某个格子,后继状态为\(SG1(n-2)\)。

另一种情况是选择了中间某个格子,那么它以及相邻两侧共三个格子都不能再选择,后继状态为\(SG1(i)\oplus SG1(n-3-i)\)。

因此列出转移方程:

\[SG1(n)=\texttt{mex}\{SG1(n-2),\texttt{mex}_{i=0}^{n-3}\{SG1(i)\oplus SG1(n-3-i)\}\} \]

这是一个\(O(n^2)\)的转移方程,但似乎并不能再优化了。

于是考虑对打出的表找规律,发现从第\(52\)项开始它就存在一个大小为\(34\)的周期,那么只要求出\(SG\)函数前\(85\)项即可。

\(k=2\)的情况

对于一个大小为\(S\)的区间,考虑其在\(k=2\)时的\(SG\)函数。

两端有限制的情况

发现只有两种可能的终止态:区间两端限制颜色不同,区间大小为\(0\)或\(1\)。

此外,发现当区间两端限制颜色不同时一次操作只会产生两个限制颜色都不同或都相同的区间,区间两端限制颜色相同时一次操作会产生一个限制颜色不同的区间和一个限制颜色相同的区间。

于是可以猜想此时的\(SG\)函数只与区间两端限制颜色是否相同有关,进而发现当限制颜色不同时\(SG\)函数值为\(0\),当限制颜色相同时\(SG\)函数值为\(1\)。

一端有限制的情况

归纳可证大小为\(S\)的区间\(SG\)值就是\(S\)。

如果我们选择在第\(i\)个位置(\(1\le i\le S\))填上与限制颜色不同的颜色,那么后继状态是\((i-1)\oplus 0\),即后继状态包含\(0\sim S-1\)。

如果我们选择在第\(i\)个位置(\(1\le i<S\))填上与限制颜色相同的颜色,那么后继状态是\((i-1)\oplus 1\),满足\((i-1)\oplus1\le i<S\)。

因此后继状态的\(\texttt{mex}\)就是\(S\),即\(SG\)值等于\(S\)。

没有限制的情况

选择在第\(i\)个位置上填入一个数的后继状态是\((i-1)\oplus(n-i)\)。

显然,只有当\(n\)是奇数的时候才有可能出现\((i-1)\oplus(n-i)=0\)。

又由于没有限制肯定是全局的情况,不需要求出具体的\(SG\)值,只要判断先手是否必胜即可。

代码:\(O(Tn)\)

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Rg register
#define RI Rg int
#define Cn const
#define CI Cn int&
#define I inline
#define W while
#define N 100000
using namespace std;
int n,k,a[N+5],vis[N+5],sg[N+5];
I int SG1(RI x) {return sg[x<=52?x:52+(x-52)%34];}//求k=1时在n个空格子中博弈的SG函数
I int SG2(CI l,CI r) {return 1<=l&&r<=n?a[l]==a[r]:r-l-1;}//求k=2时在区间(l,r)中博弈的SG函数,根据几端有限制分类
I bool Solve()
{
	RI i,j,t=0;if(k>=3) {for(i=1;i<=n;++i) !a[i]&&(t^=1);return t;}//k≥3的情况
	if(k==1) {for(j=0,i=1;i<=n;++i) a[i]&&(t^=SG1(max(j?i-j-3:i-2,0)),j=i);return t^=SG1(max(j?n-j-1:n,0)),t;}//k=1的情况
	for(i=1;i<=n&&!a[i];++i);if(i>n) return n&1;//k=2的情况(没有限制)
	for(j=0,i=1;i<=n;++i) a[i]&&(t^=SG2(j,i),j=i);return t^=SG2(j,n+1);//k=2的情况(有限制)
}
int main()
{
	RI i,j;for(sg[1]=1,i=2;i<=85;++i) {for(vis[sg[i-2]]=i,j=0;j<=i-3;++j) vis[sg[j]^sg[i-3-j]]=i;W(vis[sg[i]]==i) ++sg[i];}//预处理SG1的前85项
	RI Tt;scanf("%d",&Tt);W(Tt--) {for(scanf("%d%d",&n,&k),i=1;i<=n;++i) scanf("%d",a+i);puts(Solve()?"y":"n");}return 0;
}

标签:颜色,格子,Nim,SG1,BZOJ2410,博弈论,限制,SG,define
来源: https://www.cnblogs.com/chenxiaoran666/p/BZOJ2410.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有