LCMS
给你一个长度为n的序列A0,A1,A2,...,An−1
求∑i=0n−2∑j=i+1n−1lcm(Ai,Aj) mod 998244353
其中2≤n≤2e5,1≤Ai≤1e6
思路

对原式做等式变形
i=0∑n−2j=i+1∑n−1lcm(Ai,Aj)∗2+i=0∑n−1Ai=i=0∑n−1j=0∑n−1lcm(Ai,Aj)
又因为
Lcm(a,b)=gcd(a,b)a∗b
继续变形
i=0∑n−1j=0∑n−1lcm(Ai,Aj)=i=0∑n−1j=0∑n−1gcd(Ai,Aj)Ai∗Aj
记Ai最大值为R
问题就转化为了求
Ans=d=1∑R d1∗i=0∑n−1j=0∑n−1(Ai∗Aj)⋅[gcd(Ai,Aj)=d]
定义:
f(d)为gcd(Ai,Aj)=d的总贡献
F(d)为gcd(Ai,Aj)为d的倍数的总贡献
容易得
f(d)=i=0∑n−1j=0∑n−1(Ai∗Aj)⋅[gcd(Ai,Aj)=d]F(d)=d∣d′∑f(d′)=d∣d′∑(i=0∑n−1Ai⋅[d∣Ai]∗j=0∑n−1Aj⋅[d∣Aj])=d∣d′∑(i=0∑n−1Ai⋅[d∣Ai])2
莫比乌斯反演得
f(d)=d∣d′∑μ(dd′)⋅F(d′)
其中F(d′)可以用枚举倍数的方法,预处理出来
然后再枚举d,算出Ans
Ans=d=1∑R d1∗f(d)
不要忘了这个Ans 是∑i=0n−2∑j=i+1n−1lcm(Ai,Aj)∗2+∑i=0n−1Ai=∑i=0n−1∑j=0n−1lcm(Ai,Aj) 等式右边的答案,我们要求的是左边的那一项。
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
const ll mod = 998244353;
ll a[N], F[N], mp[N], f[N], inv[N];
int Primes[N], mbux[N], cnt;
bool vis[N];
void get_mbux(int x) {
mbux[1] = 1;
for (int i = 2; i <= x; i ++ ) {
if(!vis[i]) {
Primes[++ cnt] = i;
mbux[i] = -1;
}
for (int j = 1; j <= cnt && i * Primes[j] <= x; j ++ ) {
vis[i * Primes[j]] = 1;
if(i % Primes[j] == 0 ) {
mbux[i * Primes[j]] = 0;
break;
}
mbux[i * Primes[j]] = - mbux[i];
}
}
}
int main() {
// 线性筛求莫比乌斯
get_mbux(N-1);
// 预处理逆元
inv[1] = 1;
for (int i = 2; i <= N-1; i ++) inv[i] = inv[mod%i] * (mod-mod/i) % mod;
int n;
scanf("%d", &n);
ll Maxx = 0, sum = 0, res = 0;
for (int i = 1; i <= n; i ++ ) {
scanf("%lld", &a[i]);
Maxx = max(Maxx, a[i]);
mp[a[i]] ++;
sum += a[i];
sum %= mod;
}
// 预处理 F
for (int i = 1; i <= Maxx; i ++ ) {
for (int j = i; j <= Maxx; j += i) {
F[i] += mp[j] * j;
F[i] %= mod;
}
F[i] = (F[i] * F[i]) % mod;
}
// 算 f
for (int i = 1; i <= Maxx; i ++ ) {
for (int j = i; j <= Maxx; j += i) {
f[i] = (f[i] + mbux[j/i] * F[j] % mod + mod) % mod;
}
res = (res + inv[i] * f[i] + mod ) % mod;
}
res = ((res - sum + mod) * inv[2]) % mod;
printf("%lld\n", res);
}