首页 > 其他分享 >Nim 积

Nim 积

时间:2023-01-07 14:12:27浏览次数:64  
标签:log Nim text textbf otimes oplus

什么究极深奥博弈论啊,是不是被刻在神秘石头上了才这么神秘啊。

注意,以下定义都十分神秘,看不懂原理的话建议直接记。

推荐阅读:Nim积解法小结 - zjp_shadowNimber 系列略学习笔记 - chasedeath


  • \(\text{Nim}\) 和

即异或运算。定义为 \(x \oplus y = \text{mex}\{\{a \oplus y \mid a \in [0,x)\} \bigcup \{x \oplus b \mid b \in [0,y)\}\}\)。

从这个定义上看,左边那个集合表示从状态 \(x\) 中取走任意个石子,然后再和右边异或成为新状态,右边集合同理,而根据 \(\text{SG}\) 函数的计算需要对这些后继状态取 \(\text{mex}\)。

所以运算结果相当于两个 \(\text{Nim}\) 游戏的和。

  • 高维 \(\text{Nim}\) 游戏

一维:\(n\) 堆石子,轮流选一堆拿走任意非零个。
可以看作是数轴上撒 \(n\) 个黑点,其它都是白点,每次选一个黑点 \(a_i\),再选一个 \(x \lt a_i\),将线段 \(x \sim a_i\) 两端点颜色取反。

二维:平面上 \(n\) 个黑点,每次选一个 \((a_i,b_i)\) 再选一个 \((x \lt a_i,y \lt b_i)\),将矩形 \((x,y) \sim (a_i,b_i)\) 四个顶点颜色取反。

三维:对应偏序上升到三维,将长方体八个顶点颜色取反。

以此类推,可以发现黑点之间是互不影响的,所以总状态就是黑点的 \(\text{Nim}\) 和。

  • \(\text{Nim}\) 积

定义二维 \(\text{Nim}\) 游戏中的 \(\text{Nim}\) 积:\(x \otimes y = \text{mex}\{(a \otimes b) \oplus (a \otimes y) \oplus (x \otimes b) \mid a \in [0,x),b \in [0,y)\}\)。
从博弈意义(?)上看比较好理解。

满足以下运算律:交换律,结合律,乘法分配律。同时 \(0 \otimes x = 0, 1 \otimes x = x\)。所以这两个运算在推导上完全可以当成加法和乘法处理。

由于这个东西十分复杂,暴力计算复杂度是 \(O((xy)^2)\),非常优秀。

但是,经过伟大的数学家们不懈的努力,我们拥有了两个非常优秀的性质:

\[2^{2^{n}} \otimes x = 2^{2^{n}} \times x\;\;\;\;\text{where }x \lt 2^{2^{n}} \]

\[2^{2^{n}} \otimes 2^{2^{n}} = \dfrac{3}{2} \times 2^{2^{n}} \]

以上 \(n \in \mathbb{N}\)。证明不会。

考虑如何利用以上两个性质加速计算:

法一:
以下 \(\textbf{F}(x,y) = x \otimes y\),\(\textbf{G}(x,y) = 2^x \otimes 2^y\),“和” 表示 \(\text{Nim}\) 和,“积” 表示 \(\text{Nim}\) 积。
对于 \(x \text{ or }y \le 1\) 的情况特判,然后按位考虑,求出 \(x,y\) 每一位的积后求和即可。
对于 \(2^x \otimes 2^y\),考虑拆分成若干 \(2^{2^{n}}\) 的积进行处理。
现在再对幂次 \(x,y\) 从高到低 按位考虑,求过的位就赋值为 \(0\)。设当前这一位是 \(2^k\),如果都是 \(0\) 可以忽略,否则有两种情况:

  1. 都是 \(1\),设 \(M = 2^{2^k},A = 2^{x-2^k},B = 2^{y - 2^k}\),因为是最高位所以 \(M \gt A,B\),所以 \(\textbf{G}(x,y) = (M \otimes A) \otimes (M \otimes B)\),化简得 \(\textbf{G}(x,y) = \dfrac{3}{2}M \otimes \textbf{G}(x-2^k,y-2^k)\) ,那么递归即可;
  2. 其中一个为 \(1\),钦定这个数是 \(x\) 否则 swap 一下,则 \(M = 2^{2^k},A = 2^{x-2^{k}},B = 2^{y}\),那么 \(\textbf{G}(x,y) = M \otimes \textbf{G}(x - 2^k,y)\),还是递归计算即可。

直接按上面的写是可以的。把递归展开后分为两部分:

\[\textbf{G}(x,y) = (\otimes_{i \in \{x \text{ xor } y\}}2^{2^{i}}) \otimes (\otimes_{i \in \{x \text{ and } y\}}\dfrac{3}{2}2^{2^{i}}) \]

前半部分根据性质直接整数乘法计算,后半部分用 \(\textbf{F}\) 递归算。

需要辨别一点,每次暴力计算 \(\textbf{G}\),则总复杂度看起来是 \(O(\log x \log y \log \log x \log \log y)\)(或者可能是别的什么东西,但是肯定比下面的复杂度更高)。
注意到 \(\textbf{G}(x,y)\) 传入的参数都是 \(\log M\) 级别的,所以可以记忆化。
这样复杂度就是 \(O(\log x \log y)\),但是好像跑得很慢。

感觉这里的复杂度还是不太会算,如果有佬算出来不对就去撅一撅评论区。

#define ForBit(i,x) for(ll i=0,n=x;1ll<<i<=n;++i) if(n>>i&1)
ll s[63][63]; inline ll f(ll x,ll y);
inline ll g(int x,int y){
	if(!x||!y) return 1ll<<(x|y); if(s[x][y]!=-1) return s[x][y];
	ll t=1; int upd=x^y; ForBit(i,upd) t<<=(1<<i);
	upd=x&y; ForBit(i,upd) t=f(t,3ll<<((1<<i)-1));
	return s[x][y]=s[y][x]=t;
}
inline ll f(ll x,ll y){
	if(!x||!y) return 0; if(x==1||y==1) return max(x,y);
	ll t=0; ForBit(i,x) ForBit(j,y) t^=g(i,j); return t;
}

法二:
考虑分治,设 \(k \in \mathbb{N}\) 为最小的满足 \(2^{2^{k+1}} \gt \max(x,y)\) 的值,\(x = 2^{2^{k}} x_0+x_1\),\(y = 2^{2^{k}}y_0+y_1\),则

\[\begin{aligned} \textbf{F}(x,y) &= (x_0 \otimes 2^{2^{k}} \oplus x_1) \otimes (y_0 \otimes 2^{2^{k}} \oplus y_1)\\ &=[\dfrac{3}{2}2^{2^{k}} \otimes (x_0 \otimes y_0)] \oplus [2^{2^{k}} \otimes (x_0 \otimes y_1 \oplus x_1 \otimes y_0)] \oplus (x_1 \otimes y_1)\\ &=x_1 \otimes y_1 \oplus 2^{2^{k}}[(x_0 \oplus x_1) \otimes (x_1 \oplus y_1) \oplus x_1 \otimes y_1]\oplus 2^{2^{k}-1} \otimes x_0 \otimes y_0\end{aligned}\]

为什么这样化简,因为 \(2^{2^{k}} \gt x_0,x_1,y_0,y_1\) 且 \(\dfrac{3}{2}2^{2^k} = 2^{2^k} \oplus 2^{2^k-1}\)。

这样所有的递归传入的参数都减小了一半,复杂度 \(O(\log x \log y)\)。

  • 例题

  1. [ABC274Ex] XOR Sum of Arrays

洛谷翻译有没有素质?

题意:\(q\) 次询问 \(a[b,c]\) 按位异或 \(a[d,e]\) 的结果字典序是否小于 \(a[f,g]\)。\(n \le 5 \times 10^5\),\(q \le 5 \times 10^4\)。

Sol:显然的哈希二分,难点在于哈希函数,我们需要设计一种函数使得 \(h(a \oplus b) = h(a) \oplus h(b)\),其中 \(a,b\) 是等长序列。
考虑使用 \(\text{Nim}\) 数系,那么根据基础字符串哈希知识得到 \(h(a + \{x\}) = h(a) \otimes base \oplus x\),并且显然满足上述条件。
于是你就切了一道满红 *3191 的题。复杂度 \(O(n \log^2 M + q \log n \log^2 M)\)。

说句闲话,法一会被卡 RE

inline ull NimProd(ull x,ull y,int p=64){
	if(x<=1||y<=1) return x*y; if(p<=8&&(~s[x][y])) return s[x][y];
	p>>=1; ull x0=x>>p,x1=x&((1ull<<p)-1),y0=y>>p,y1=y&((1ull<<p)-1),
			   xy0=NimProd(x0,y0,p),xy1=NimProd(x1,y1,p),xy=NimProd(x0^x1,y0^y1,p),
			   res=NimProd(xy0,1ull<<(p-1),p)^xy1^((xy1^xy)<<p);
	assert((xy1^xy)<(1ull<<p));
	if(p<8) s[x][y]=s[y][x]=res; return res;
}
inline ull Val(int l,int r){ return h[r]^NimProd(h[l-1],pw[r-l+1]); }
inline int LCP(int s1,int s2,int s3,int len){
	int l=0,r=len,mid,ans=0;
	while(l<=r) mid=l+r>>1,((Val(s1,s1+mid-1)^Val(s2,s2+mid-1))==Val(s3,s3+mid-1))?(ans=mid,l=mid+1):(r=mid-1);
	return ans;
}

main(){
	memset(s,-1,sizeof(s));
	rd(n),rd(m),pw[0]=1,B=rnd();
	for(int i=1;i<=n;++i)
		rd(a[i]),h[i]=NimProd(h[i-1],B)^a[i],pw[i]=NimProd(pw[i-1],B);
	while(m--){
		int l1,r1,l2,r2,l3,r3,len1,len2;
		rd(l1),rd(r1),rd(l2),rd(r2),rd(l3),rd(r3);
		int lcp = LCP(l1,l2,l3,min((len1=r1-l1+1),(len2=r3-l3+1)));
		if(lcp<min(len1,len2)) puts((a[l1+lcp]^a[l2+lcp])<a[l3+lcp]?"Yes":"No");
		else puts(len1<len2?"Yes":"No");
	}
}

标签:log,Nim,text,textbf,otimes,oplus
From: https://www.cnblogs.com/suitlie/p/17032560.html

相关文章

  • 题解 : Luogu P2197 【模板】nim 游戏
    题目链接:link结论如果$a_1\oplusa_2\oplus...\oplusa_n\not=0$,则先手必胜证明操作到最后时,每堆石子数都是\(0\),\(0\oplus0\oplus...\oplus0=0......
  • Unity小地图Minimap制作全面功能介绍篇
    本系列文章将讲述如何制作小地图。功能如下:  小地图的局部放大地图,缩小功能。小地图展开成为大地图,以及与大地图的互相切换  大地图的人物图标跟随角色旋转和移动 ......
  • Unity创建Animation动画无法播放问题
    前提:我是要使用animation的方式去播放动画,而不是animator状态机;是针对unity自己制作的动画,而不是外部导入进来的动画。 发现一个问题,我在unity中给一个cube创建一个animat......
  • Unity3D之sprite动画(Animation)的制作
    实例说明:忍者跑酷的player动画制作。。。这些都是用Sprite做的动画。。。在prioject面板里的一组sprite里面点击,之后看属性面板的SpriteEditor对这组Sprite进行编辑。。。......
  • [LeetCode] 2244. Minimum Rounds to Complete All Tasks
    Youaregivena 0-indexed integerarray tasks,where tasks[i] representsthedifficultylevelofatask.Ineachround,youcancompleteeither2or3tas......
  • 【李宏毅深度学习】(task5)网络设计技巧1—Local Minimum和鞍点
    学习心得(1)当loss无法继续下降时,可能是因为卡在criticalpoint,但不能说是卡在localminima,因为saddlepoint也是微分为0的点(2)如果hessian矩阵的所有的特征值eigenvalue都是......
  • 简单聊下.NET6 Minimal API的使用方式(转)
    前言#    随着.Net6的发布,微软也改进了对之前ASP.NETCore构建方式,使用了新的MinimalAPI模式。之前默认的方式是需要在Startup中注册IOC和中间件相关,但是在MinimalA......
  • 【题解】P5298 [PKUWC2018]Minimax
    P5298[PKUWC2018]Minimax思路线段树合并优化树形dp.值域1e9首先考虑离散化。然后发现需要维护每种权值的出现概率,于是可以考虑到一个简单的树形dp:设\(f[i][j]\)......
  • 「反Nim」数列游戏
    本题为12月27日22寒假集训每日一题题解题目来源:(未知)题面题目描述cad和jyx最近迷上了一款名为插入数列的游戏,有一个n行m列的网格,你每次可以按下1个或多个格子,但必......
  • ExtJS 动画(Animate)
    ExtJSelement对象动画渐入动画//使用默认参数els.fadeIn();//自定义动画参数els.fadeIn({opacity:.75,duration:2000});//自定义动画参数els.fadeIn({o......