LCMS

给你一个长度为nn的序列A0,A1,A2,...,An1A_0,A_1,A_2,...,A_{n-1}

i=0n2j=i+1n1lcm(Ai,Aj) mod 998244353\sum_{i=0}^{n-2}\sum_{j=i+1}^{n-1}lcm(A_i,A_j)\ mod\ 998244353

其中2n2e5,1Ai1e62\le n \le 2e5,1 \le A_i \le 1e6

思路

alt

对原式做等式变形

i=0n2j=i+1n1lcm(Ai,Aj)2+i=0n1Ai=i=0n1j=0n1lcm(Ai,Aj)\sum_{i=0}^{n-2}\sum_{j=i+1}^{n-1}lcm(A_i,A_j)*2 + \sum_{i=0}^{n-1} A_i= \sum_{i=0}^{n-1}\sum_{j=0}^{n-1}lcm(A_i,A_j)

又因为

Lcm(a,b)=abgcd(a,b)Lcm(a,b)=\frac{a*b}{gcd(a,b)}

继续变形

i=0n1j=0n1lcm(Ai,Aj)=i=0n1j=0n1AiAjgcd(Ai,Aj)\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}lcm(A_i,A_j) \\=\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}\frac{A_i*A_j}{gcd(A_i,A_j)} \\

AiA_i最大值为RR

问题就转化为了求

Ans=d=1R 1di=0n1j=0n1(AiAj)[gcd(Ai,Aj)=d]Ans =\sum_{d=1}^{R}\ \frac{1}{d}*\sum_{i=0}^{n-1}\sum_{j=0}^{n-1} (A_i*A_j)\cdot[gcd(A_i,A_j)=d]

定义:

f(d)f(d)gcd(Ai,Aj)=dgcd(A_i,A_j)=d的总贡献

F(d)F(d)gcd(Ai,Aj)gcd(A_i,A_j)dd的倍数的总贡献

容易得

f(d)=i=0n1j=0n1(AiAj)[gcd(Ai,Aj)=d]F(d)=ddf(d)=dd(i=0n1Ai[dAi]j=0n1Aj[dAj])=dd(i=0n1Ai[dAi])2\begin{aligned} & f(d)=\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}(A_i*A_j)\cdot[gcd(A_i,A_j)=d] \\ &F(d)=\sum_{d|d'}f(d') \\ &=\sum_{d|d'} (\sum_{i=0}^{n-1}A_i\cdot[d|A_i]*\sum_{j=0}^{n-1}A_j\cdot[d|A_j]) \\ &=\sum_{d|d'} (\sum_{i=0}^{n-1}A_i\cdot[d|A_i])^2 \end{aligned}

莫比乌斯反演得

f(d)=ddμ(dd)F(d)f(d)=\sum_{d|d'}\mu(\frac{d'}{d})\cdot F(d')

其中F(d)F(d')可以用枚举倍数的方法,预处理出来

然后再枚举dd,算出AnsAns

Ans=d=1R 1df(d)Ans =\sum_{d=1}^{R}\ \frac{1}{d} *f(d)

不要忘了这个AnsAnsi=0n2j=i+1n1lcm(Ai,Aj)2+i=0n1Ai=i=0n1j=0n1lcm(Ai,Aj)\sum_{i=0}^{n-2}\sum_{j=i+1}^{n-1}lcm(A_i,A_j)*2 + \sum_{i=0}^{n-1} A_i= \sum_{i=0}^{n-1}\sum_{j=0}^{n-1}lcm(A_i,A_j) 等式右边的答案,我们要求的是左边的那一项。

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);
}