魔法手链

先拓展一个之前讲过的模型的性质

对于一个编号在[0,n)的环(顺时针编号),从编号为x的点开始顺时针跳,每次跳k步,那么最终经过的点一共有nd个(其中d=gcd(n,k)),如果我们将这nd个点按照编号顺序排成一个圆(不是按经过的顺序),那么相邻两个点之间的距离为d

证明:显然将这nd个点按照编号顺序排成一个圆后,这个圆的总长度为n(相邻两点之间的距离为两点编号差的绝对值)。考虑每个点的编号的形式,为x+t1kt2n,因为是从x每次跳k步,当跳过n时就要减去n,所以编号的形式就是k,n的线性组合。故编号可以写作x+td,也就是说相邻两个点的距离是d的倍数,至少为d;而总长度为n,当且仅当任意相邻两个点之间的距离为d才为n(否则的话会更大),证毕

有了这个性质,我们就可以知道,原图一共被分成了d个环,每个环的起点为x,x+1,x+2,...,x+d1

现在我们考虑Burnside引理,假设我们现在已经获得了S(也就是满足题意的所有涂色方案),置换群G即顺时针旋转0,1,2,...,n1步,我们现在要求的就是|S/G|,只需要求|Sg|

现在我们考虑对于一个固定的g(也就是每次跳的步数k已经知道了),那么根据上面的结论,我们只用考虑0,1,2,...,d1d个点构成的环满足题意的涂色方案一共有多少种就好了

为什么这里不能用Polya定理:Polya定理的内容就是|Bc(g)|=|Sg|,可以想一下这个为什么成立,主要原因还是因为各个循环置换之间互不影响,所以可以任意涂色;而这里显然是会互相影响的,所以只能用Burnside引理

计算d个点构成的环满足题意的涂色方案一共有多少种:很显然的环形DP,但是这里时间复杂度卡的比较紧,如果采用容斥原理(即按照线形计算,最后强制第一个点和最后一个点涂相同颜色)的话会超时(因为你要枚举第一个点涂的颜色),此时有一个优化:不采用容斥原理,而是采用正面计算,将f从一维变成二维,i[0,m),f[i][i]=1,这就是说第i个行向量表示第一个点只能涂第i种颜色,最后得到的数组经过的时间为d+1(注意不是d,因为我们要求最后一个点和第一个点涂的颜色相同,这里相当于断环成链了),然后加上f的对角线就好了

计算完f后,我们还不能枚举g,因为n太大了,此时肯定只能枚举d,最后不难知道要计算ϕ(nd),这种计算约数的欧拉函数的技巧见这篇总结

posted @   最爱丁珰  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示