题目大意:
项链和手镯都是若干珠子穿成的环形首饰,手镯可以旋转和翻转,但项链只能旋转,给n个珠子,t种颜色,求最后能形成的手镯,项链的数量
这里根据等价类计数的polya定理求解
对于一个置换f,若一种方案经过置换后不改变,那么不改变的点的个数记作C(f)
统计所有的C(f) , 相加之后求和除以置换的种数即可
那么这道题里面
对于项链来说,旋转一个角度,也就是2*PI/n , 那么置换群可表示为
1 2 3 4 .... n
2 3 4 5 ... 1
这里就存在一个循环节
所以方案数为 t^1
自己 写着会发现,循环节的个数就是旋转数和总数的gcd值
那么不动点的个数就是 sigma(t^(gcd(i,n))
对于手镯除了上述情况,还有翻转
对于 n 为奇数,翻转对称轴有n条,这样置换形成的循环节有 (n+1)/2
对于 n 为偶数,翻转对称轴有n条,n/2条是不经过点的,这样置换形成的循环节有 (n)/2
n/2条经过两个点的,这样置换形成的循环节有 (n)/2+1
#include <cstdio>
#include <cstring> using namespace std;
#define ll unsigned long long
int n , t;
ll pow[]; int gcd(int a , int b){return b==?a:gcd(b , a%b);} void init()
{
pow[] = t;
for(int i= ; i<=n ; i++) pow[i] = pow[i-]*t;
}
int main()
{
// freopen("in.txt" , "r" , stdin);
while(~scanf("%d%d" , &n , &t)){
init();
ll a= , b=;
for(int i= ; i<=n ; i++){
a += pow[gcd(i , n)];
}
if(n&) b+= pow[(n+)/]*n;
else{
b+=(n/)*(pow[n/]+pow[n/+]);
}
printf("%lld %lld\n" , a/n , (a+b)//n);
}
}