题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35397
【思路】
Polya定理。
旋转:循环节为gcd(i,n),i为偏移距离。
翻转:当n为偶数时,对称轴过点时循环节为n/2+1有n/2个,不过点时循环节为n/2有n/2个。
使用polya定理进行计数即可。
【代码】
#include<cstdio>
using namespace std; typedef long long LL;
const int N = +; LL pow[N];
int n,t; int gcd(int a,int b) {
return (!b)? a:gcd(b,a%b);
} int main() {
pow[]=;
while(scanf("%d%d",&n,&t)==) {
for(int i=;i<=n;i++) pow[i]=t*pow[i-];
LL a=;
for(int i=;i<n;i++) a += pow[gcd(i,n)];
LL b=;
if(n&) b=n*pow[(n+)/];
else b=n/*(pow[n/+]+pow[n/]);
printf("%lld %lld\n",a/n,(a+b)//n);
}
return ;
}