题意:
项链和手环都是若干珠子构成的环形首饰,手环可以翻转,项链不行,例如下图中的两个手环是相同的。不论是手环还是项链,在旋转之后一样则视为相同。
给定n和t,输出用t种颜色的珠子(每种无限个),制作成n个珠子组成的项链和手环个数。
数据范围:n<=50,t<=10
解法:
显然是等价类计数问题
题目存在两种置换:翻转和旋转
项链只有旋转置换
手环有旋转和翻转两种置换
将珠子标号为0-(n-1)
旋转:
考虑珠子间隔为i的循环,那么每个循环中珠子数量为n/gcd(n,i),共有gcd(n,i)个循环。
珠子数量为n/gcd(n,i)的证明:循环中珠子标号为0,i,2i,3i…(t-1)i%n。因为是循环,那么t i%n=0,t i=k n,k取所有满足条件的k中的最小值。当ti=lcm(i,n)的时候,t和k为最小值,此时ti=lcm(i,n)->t=lcm(i,n)/i=i n/gcd(i,n)/i=n/gcd(i,n)。
那么不动点的数量为tgcd(i,n)。
对i=0到n-1的每个i的不动点求和即可,即sum(tgcd(i,n))。
翻转:
1.n为奇数时,有n个对称轴,每个对称轴左右两边的对称点是一个循环,一共(n-1)/2个循环,对称轴上有一个点单独是一个循环,那么一共(n+1)/2个循环。那么不动点总数量为nt(n+1)/2
2.n为偶数时,对称轴有两种,一种对称轴穿过珠子,一种不穿。穿过珠子的对称轴有n/2条,每个对称轴有(n-2)/2个对称循环和2个单点循环,循环数为(n+2)/2。不穿过珠子的对称轴有n/2条,每个对称轴有n/2个循环。综上得不动点的总数量为n/2(t(n+2)/2+tn/2)
计算出不动点总数,根据Polya定理计算平均值就是答案。
项链除以n,手环除以2n
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e5+5;
int n,t;
int ppow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
signed main(){
while(cin>>n>>t){
//旋转
int sum1=0;
for(int i=1;i<=n;i++){
sum1+=ppow(t,__gcd(n,i));
}
//翻转
int sum2=0;
if(n%2){
sum2+=n*ppow(t,(n+1)/2);
}else{
sum2+=n/2*(ppow(t,(n+2)/2)+ppow(t,n/2));
}
//输出
cout<<sum1/n<<' '<<(sum1+sum2)/(2*n)<<endl;
}
return 0;
}