P4980 Pólya 定理 + DFS
作者:互联网
题意
题解
根据 Pólya 定理,本质不同的染色方案数为
1
n
∑
k
=
0
n
−
1
n
g
c
d
(
n
,
k
)
\frac{1}{n}\sum\limits_{k=0}^{n-1}n^{gcd(n,k)}
n1k=0∑n−1ngcd(n,k) 式中满足
g
c
d
(
n
,
k
)
=
d
gcd(n,k)=d
gcd(n,k)=d 的
k
k
k 的数量为
ϕ
(
n
/
d
)
\phi(n/d)
ϕ(n/d),合并这样的项得到
1
n
∑
d
∣
n
ϕ
(
d
)
n
n
/
d
\frac{1}{n}\sum\limits_{d\vert n}\phi(d)n^{n/d}
n1d∣n∑ϕ(d)nn/d 预处理出
n
n
n 的素因子,
D
F
S
DFS
DFS 计算所有的约数并统计答案即可。总时间复杂度
O
(
t
(
n
+
∑
d
∣
n
log
n
)
)
O\Big(t(\sqrt{n}+\sum\limits_{d\vert n}\log{n})\Big)
O(t(n
+d∣n∑logn))。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7, MAXLG = 35;
int pn, prime[MAXLG], num[MAXLG];
int T, N;
ll Res;
ll pow_mod(ll x, int n, int mod)
{
ll res = 1;
while (n)
{
if (n & 1)
res = res * x % mod;
x = x * x % mod, n >>= 1;
}
return res;
}
void dfs(int k, int n, int ph, int d)
{
if (k == pn)
{
Res = (Res + pow_mod(N, N / d, MOD) * ph % MOD) % MOD;
return;
}
int p = prime[k];
if (n < num[k])
dfs(k, n + 1, ph * (n == 0 ? p - 1 : p), d * p);
dfs(k + 1, 0, ph, d);
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> T;
while (T--)
{
cin >> N;
pn = Res = 0;
int t = N;
for (int i = 2; i * i <= t; ++i)
if (t % i == 0)
{
prime[pn] = i, num[pn] = 0;
while (t % i == 0)
t /= i, ++num[pn];
++pn;
}
if (t != 1)
prime[pn] = t, num[pn++] = 1;
dfs(0, 0, 1, 1);
cout << Res * pow_mod(N, MOD - 2, MOD) % MOD << '\n';
}
return 0;
}
标签:P4980,dfs,int,ll,DFS,num,lya,pn,mod 来源: https://blog.csdn.net/neweryyy/article/details/122396087