CF585E
令 sn 表示最大公因数恰好为 n 的集合个数,fn 表示与 n 互质的数的个数。
那么我们要求的就是 ∑isifi。
考虑求出 s 和 f。
考虑计算 fi。令 ci 表示数 i 的出现次数。
则直接莫比乌斯反演:
fn=∑i[gcd(i,n)=1]ci
=∑ici∑d∣i,d∣nμ(d)
=∑d∣nμ(d)∑d∣ici
令 gk=∑k∣ici,g′k=μ(k)gk,那么 fn=∑d∣ng′d
发现这个 gi 就表示 i 的倍数的出现次数。
再考虑求 si。我们令 s′i 表示最大公因数为 i 的倍数的方案数。要使最大公因数为 i 的倍数,那么每个选的数必须是 i 的倍数。所以容易得到 s′i=2gi−1。
又有 s′i=∑i∣dsd。
观察上面的式子的形式,它们都是这样的形式:
bk=∑i∣kai
bk=∑k∣iai
其中,上面的式子为狄利克雷前缀和,下面的式子为狄利克雷后缀和。
这都可以在 O(wloglogw) 的时间内求出,可以先去做一下【模板】Dirichlet 前缀和(这个实际上就是一个关于质因子分解后的指数的高维前缀和,使用类似 FMT 的方法就可以了)。
计算 g 和 f 都是标准的狄利克雷前/后缀和形式。
但还有个问题,已知 a 求 b 能做了,但是那个 s 的计算,是已知 b 求 a 的。
前面是加,那现在就把它改成减就可以了。当然也可以用高维前缀和的知识解释。
总时间复杂度 O(n+wloglogw)。
具体细节看代码。
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 500005, M = 10000000, mod = 1e9 + 7;
int n, ans;
int a[N], cnt[M+5];
int mu[M+5];
int pri[M / 10], tot;
bool vis[M+5];
int pw[N];
int f[M], g[M];
inline void add(int &a, int b) {
a += b;
if (a >= mod) a -= mod;
if (a < 0) a += mod;
}
void init(int n) {
pw[0] = 1;
for (int i = 1; i <= 500000; ++i) pw[i] = 1ll * pw[i - 1] * 2 % mod;
mu[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!vis[i]) pri[++tot] = i, mu[i] = -1;
for (int j = 1; j <= tot && i * pri[j] <= n; ++j) {
vis[i * pri[j]] = 1;
if (i % pri[j] == 0) {
mu[i * pri[j]] = 0;
break;
}
mu[i * pri[j]] = -mu[i];
}
}
}
int main() {
init(M);
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), ++cnt[a[i]];
for (int i = 1; i <= tot; ++i)
for (int j = M / pri[i]; j; --j)
add(cnt[j], cnt[j * pri[i]]);
for (int i = 1; i <= M; ++i) g[i] = cnt[i] * mu[i];
for (int i = 1; i <= tot; ++i)
for (int j = 1; j * pri[i] <= M; ++j)
add(g[j * pri[i]], g[j]);
for (int i = 1; i <= M; ++i) f[i] = pw[cnt[i]] - 1;
for (int i = 1; i <= tot; ++i)
for (int j = 1; j * pri[i] <= M; ++j)
add(f[j], -f[j * pri[i]]);
for (int i = 2; i <= M; ++i) add(ans, 1ll * f[i] * g[i] % mod);
printf("%d", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话