求长度为 (n) 的环染色方案数,旋转翻转同构。
直接从 Polya 定理开始。
考虑一下这个置换群长怎么样:
发现可以用二元组 ((x,y) (x in [0,n),y in {0,1})) 来描述每一个元素,表示旋转度数和是否翻转。
先考虑 (y=0),这是经典结论,循环数为 (gcd(x,n))。
再考虑 (y=1)。考虑操作 (n-(x+p)mod n),画画发现可能会两两配对。
考虑它的复合:(n-(n-(x+p)+p)=x),竟然真的配对了。
但是显然奇数一定有孤立的。
这个时候奇偶要分开讨论。
我们考虑方程 (n-x-p equiv x pmod n) 的解。
显然模数是奇数的时候有逆元,所以有唯一一个孤立点,循环数为 (frac{n+1}{2})。
当模数是偶数时,如果 (n-p) 是奇数,方程无解,有 (frac{n}{2}) 个循环。
否则根据值域得出所有可行的 (x),当 (p leq frac{n}{2}),则 (x=frac{n+p}{2}) 和 (frac{2n+p}{2}),否则是 (frac{2n+p}{2}) 和 (frac{3n+p}{2})。
此时循环数为 (frac{n+2}{2})。
用 Polya 公式,即颜色循环数次方求和除以群大小,即可。
#include <iostream>
#include <cstdio>
using namespace std;
#define LLI long long
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int fastpow(int a,int b){int res=1;
for(;b;b>>=1,a=a*a)if(b&1)res=a*res;return res;}
int main(){
int a,b;LLI ans;
while(scanf("%d%d",&a,&b)==2){
if(a==0&&b==0)break;
ans=0;
for(int i=1;i<=b;++i)ans+=fastpow(a,gcd(i,b));
if(b&1)ans+=1LL*b*fastpow(a,b+1>>1);
else ans+=1LL*(a+1)*(b>>1)*fastpow(a,b>>1);
ans/=b<<1;
printf("%lld
",ans);
}
return 0;
}