
这是做的第一道群论题,自然要很水又很裸。注意用long long。
就是用到了两个定理
burnside :不等价方案数=每个置换的不动置换方案数的和 / 置换个数
polya: 一个置换的不动置换方案数=k^(这个置换的循环个数)
先看第一个博客再看第二个
http://endlesscount.blog.163.com/blog/static/82119787201221324524202/
这两个蛮好的,上代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std; int n; long long mi(int a)
{
long long ans = , zan = ;
while (a)
{
if (a & ) ans *= zan;
zan *= zan;
a >>= ;
}
return ans;
} int gcd(int a, int b)
{
if (!b) return a;
return gcd(b, a%b);
} int main()
{
scanf("%d", &n);
while (n != -)
{
if (n == )
{
printf("0\n");
scanf("%d", &n);
continue;
}
int Gcount = *n;
long long ans = ;
for (int i = ; i <= n; ++i)
ans += mi(gcd(i,n));
if (n % == ) ans += mi(n/)*n/ + mi(n/+)*n/;
else ans += mi(n/+)*n;
printf("%I64d\n", ans / Gcount);
scanf("%d", &n);
}
return ;
}