魔法手链

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

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

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

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

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

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

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

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

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

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值