扯回正题,此题需要知道的是置换群的概念,这点在刘汝佳的书中写的比较详细,此处不多做赘述。此处多说一句的是第二种手镯的情况。在下图中“左图顺时针转1个位置”和“右图顺时针旋转5个位置”是相同的,所以在最终结果处需要(ans1+ans2)/2。
可以看刘汝佳白书,来看,这道题,burnside引理和polya定理的经典应用。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 #define ll long long 7 using namespace std; 8 9 int n,m; 10 ll a[57]; 11 12 int gcd(int a,int b) 13 { 14 return b?gcd(b,a%b):a; 15 } 16 int main() 17 { 18 while(~scanf("%d%d",&n,&m)) 19 { 20 a[0]=1; 21 for (int i=1;i<=n;i++) 22 a[i]=a[i-1]*m; 23 ll x=0,y=0; 24 for (int i=1;i<=n;i++) 25 x+=a[gcd(i,n)]; 26 if (n%2==1) y=a[(n+1)/2]*n; 27 else y=(a[n/2]+a[n/2+1])*n/2; 28 printf("%lld %lld ",x/n,(x+y)/2/n); 29 } 30 }