题目大意:
n 个珠子组成的 项链,t 种颜色去染, 问有多少本质不同的项链;
经旋转,翻转一样的视为同一种项链。
就是一个简单的polya组合计数的应用,
算出每种置换的循环节个数,答案就是《组合数学》 P393 的公式;
因为题目的量比较小,直接暴搞就可以了,答案保证不会超64位,所以就没有必要高精度了。
秀一下。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define nMax 1010
#define inf 0x7fffffff
#define LL long long
template<typename T>
T gcd(T a,T b) { return b==0 ? a : gcd(b,a%b);}
LL Exp(LL a, int n){
if( n==0 ) return 1LL;
LL k = Exp(a,n/2);
k *= k;
if(n&1) k*=a;
return k;
}
LL rotate(int n,int t){
LL ans = 0;
for(int i=1;i<=n;i++) ans += Exp( (LL)t,gcd(i,n) );
return ans;
}
LL split(int n,int t){
if( n&1 ) {
return (LL)n * Exp( (LL)t,(n+1)/2 );
}else {
return (LL)(n/2) * Exp( (LL)t, n/2 ) * (1 + t);
}
}
int main(){
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,t;
while(~scanf("%d%d",&n,&t)){
LL ans = rotate(n,t);
LL s1 = ans / n;
ans += split(n,t);
LL s2 = ans / n / 2;
printf("%lld %lld\n",s1,s2);
}
return 0;
}