题目
https://www.luogu.com.cn/problem/P4980
思路
看了一晚上的群论,也就记住了前面几条定理和结论……
还是先写一下结论吧:
∣
X
/
G
∣
=
1
∣
G
∣
∑
g
∈
G
X
g
|X/G|=\frac{1}{|G|}\sum_{g∈G}X^g
∣X/G∣=∣G∣1g∈G∑Xg
其中,
X
g
X^g
Xg 为
X
X
X 在
g
g
g 作用下的不动点的数量
说人话就是: X X X 在群 G G G 作用下的等价类总数等于每一个 g g g 作用于 X X X 的不动点的算数平均值。
然后我们可以把这个东西改写一下:
∣
X
/
G
∣
=
1
∣
G
∣
∑
g
∈
G
m
c
(
g
)
|X/G|=\frac{1}{|G|}\sum_{g∈G}m^{c(g)}
∣X/G∣=∣G∣1g∈G∑mc(g)
其中
m
m
m 表示卡用颜色数,
c
(
g
)
c(g)
c(g) 表示环个数
然后这题就反演一下就行啦
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll power(ll x,ll t)
{
ll b=1;
while(t)
{
if(t&1) b=b*x%mod; x=x*x%mod; t>>=1;
}
return b;
}
ll phi(ll x)
{
ll ans=x;
for(int i=2; i<=sqrt(x); i++)
{
if(x%i) continue;
ans=ans-ans/i;
while(x%i==0) x/=i;
}
if(x!=1) ans=ans-ans/x;
return ans;
}
int main()
{
// init();
int T; scanf("%d",&T);
while(T--)
{
ll n;
scanf("%lld",&n); ll ans=0,t=sqrt(n);
for(int i=1; i<=t; i++)
{
if(n%i!=0) continue;
(ans+=phi(i)*power(n,n/i-1)%mod)%=mod;
if(i*i!=n) (ans+=phi(n/i)*power(n,i-1)%mod)%=mod;
}
printf("%lld\n",ans);
}
}