裸polya定理,已知有3种颜色的珠子,问用m个珠子能形成多少种项链(可旋转,可对称)
polya定理:ans=(m^c1+m^c2+m^c3.....)/|G|
m为颜色数,c为每种置换的循环节数,|G|为置换的个数
具体到项链:项链顺时针旋转i个,循环节数为gcd(n,i)
翻转时,n为奇数,有n个循环节为(n+1)/2的循环群
n为偶数,有n/2个循环节为(n+2)/2,和n/2个循环节为n/2的循环群
这道题就当模板了
#include<iostream>
using namespace std;
long long poww(long long a,long long b)
{
long long ans=1;
while(b--) ans*=a;
return ans;
}
int gcd(int a,int b)
{
int r=0;
while(b!=0)
{
r=a%b;
a=b;
b=r;
}
return a;
}
int main()
{
int m;
while(cin>>m)
{
if(m==0)
{
cout<<"0"<<endl;
continue;
}
if(m==-1) break;
long long ans=0;
for(int i=1;i<=m;i++) ans+=poww(3,gcd(m,i));
if(m%2==1) ans+=m*poww(3,(m+1)/2);
else ans+=m/2*poww(3,(m+2)/2)+m/2*poww(3,m/2);
cout<<ans/(2*m)<<endl;
}
}