题目大意:给定一个n个点的环,可以旋转和翻转,要求涂上c种不同的颜色,问等价类数目
首先我们不考虑翻转 假设一次旋转k个位置 那么循环个数显然是Gcd(n,i)
现在考虑翻转 易知所有的置换都可以由【沿着某个固定的对称轴翻转】和【旋转】两步组成
观察一个环 比如我们将对称轴设定为1号节点与圆心的连线 一次旋转k个位置
那么每次置换x会被换到((n+2)-x+k-1)%n+1的位置
我们会发现置换两次之后x就回到了原位
乍一看每个置换都是(AB)(CD)(EF)这样的形式 但是我们忽视了可能一个点置换后还在原点的情况
此时2x≡k+2 (mod n)
由于x<=n,因此等式成立只有两种情况:
2x=k+2 或 2x=n+k+2
当n为奇数时 k+2与n+k+2异号 两个等式中只有一个可以成立 置换是(A)(BC)(DE)(FG)的形式
当n为偶数时
如果k是奇数 那么k+2和n+k+2都是奇数 等式无解 置换是(AB)(CD)(EF)(GH)的形式
如果k是偶数 那么k+2和n+k+2都是偶数 等式有两个解 置换是(A)(B)(CD)(EF)(GH)的形式
因此对于每种置换我们都能求出循环的个数,用所有c的循环个数次幂之和除以置换数2n就是答案
注意n<=2时翻转与否是同一置换,因此每个置换被计算了两次,但是平均值不变,不影响答案
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,c;
long long Quick_Power(long long x,long long y)
{
long long re=1;
while(y)
{
if(y&1) re*=x;
x*=x; y>>=1;
}
return re;
}
int main()
{
int i;
while(cin>>c>>n,c||n)
{
long long ans=0;
for(i=0;i<n;i++)
{
ans+=Quick_Power(c,__gcd(n,i));
if(n&1)
ans+=Quick_Power(c,n+1>>1);
else
ans+=Quick_Power(c,(n>>1)+(~i&1));
}
cout<<ans/2/n<<endl;
}
return 0;
}