题意:用k中不同的颜色涂n个环上的点。
等价类1:旋转任意个点
等价类2:旋转任意个点+以任意对称轴翻转
求两个等价类数目
解法:
1.求每个等价类的不动点总数。
1.1旋转i个点的循环数目为:gcd(i,n)
1.2旋转i个点的不动点数目:k^(gcd(i,n))
1.3总不动点数目:
∑n−1i=0kgcd(i,n)
1.4同理可以求出翻转的总不动点数
2.利用Burnside公式即可求出等价类数目。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<math.h>
#include<set>
#define MP make_pair
#define ll long long
using namespace std;
const int maxn = 100;
ll n,t;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
int main(){
while(scanf("%lld%lld",&n,&t)!=EOF){
ll pow[maxn];
pow[0]=1;
for(ll i=1;i<=n;i++) pow[i]=pow[i-1]*t;
ll a=0;
for(ll i=0;i<n;i++) a+=pow[gcd(i,n)];
ll b=0;
if(n%2==1) b=n*pow[(n+1)/2];
else b=n/2*(pow[n/2+1]+pow[n/2]);
printf("%lld %lld\n",a/n,(a+b)/2/n);
}
return 0;
}