[AGC038C] LCMs
题目描述
- 给定一个长度为 \(N\) 的数列 \(A_1, A_2, A_3, \ldots, A_N\)。
- 请你求出 \(\sum_{i=1}^{N}\sum_{j=i+1}^{N}\mathrm{lcm}(A_i,A_j)\) 的值模 \(998244353\) 的结果。
- \(1 \leq N \leq 2 \times 10^5\),\(1 \leq A_i \leq 10^6\)。
- $ 1\ \leq\ N\ \leq\ 200000 $
- $ 1\ \leq\ A_i\ \leq\ 1000000 $
思路点拨
这种题目还是很好想到莫比乌斯反演的。我们对于序列中的每一个数记录出现的次数 \(cnt_i\) ,这就是指 \(i\) 在 \(A\) 的出现次数。我们先对原来的式子进行转化。
\[\sum_{i=1}^n\sum_{j=i+1}^n \text{lcm} (A_{i},A_{j})
\]
\[\dfrac{1}{2}(\sum_{i=1}^N \sum_{j=1}^N \text{lcm}(i,j)\times cnt_icnt_j -\sum_{i=1}^n A_i)
\]
我们暂且讨论 $\sum_{i=1}^N \sum_{j=1}^N \text{lcm}(i,j)\times cnt_icnt_j $ 的部分:
\[\sum_{i=1}^N\sum_{j=1}^N \dfrac{ij}{\gcd(i,j)}cnt_icnt_j
\]
\[\sum_{d=1}^N \sum_{i=1}^N\sum_{j=1}^N \dfrac{ij}{d}cnt_icnt_j[\gcd(i,j)=d]
\]
\[\sum_{d=1}^N d\sum_{i=1}^{\lfloor \frac{N}{d}\rfloor} \sum_{j=1}^{\lfloor \frac{N}{d}\rfloor}ij\times cnt_{id} cnt_{jd}[\gcd(i,j)=1]
\]
\[\sum_{d=1}^N d \sum_{k=1}^{\lfloor \frac{N}{d}\rfloor} \mu(k) (\sum_{k=1}^{\lfloor \frac{N}{kd}\rfloor} k\times cnt_{kd})^2
\]
我们令 \(T=kd\) 那么
\[\sum_{T=1}^N \sum_{d|T} d\mu(\dfrac{T}{d})(\sum_{i=1}^{\lfloor \frac{N}{T} \rfloor} \dfrac{T}{d}cnt_T)^2
\]
\[\sum_{T=1}^N \sum_{d|T} \dfrac{1}{d}\mu(\dfrac{T}{d})(\sum_{i=1}^{\lfloor \frac{N}{T} \rfloor} Tcnt_T)^2
\]
括号内的式子和逆元 \(O(n \log n)\) 预处理就可以了。这样全部的式子都可以在 \(O(n \log n)\) 的时间内计算。
这里给出一份代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int mod=998244353;
int qpow(int a,int b){
int ans=1,base=a;
while(b){
if(b&1) ans=ans*base%mod;
base=base*base%mod;
b>>=1;
}
return ans;
}
const int MAXN=1e6+10,N=1e6;
int n,A[MAXN],cnt[MAXN];
int mu[MAXN],inv[MAXN],f[MAXN];
int temp[MAXN],g[MAXN];
bool vis[MAXN];
void init(){
inv[0]=1;
for(int i=1;i<=N;i++){
mu[i]=1;
inv[i]=qpow(i,mod-2);
}
for(int i=2;i<=N;i++){
if(vis[i]) continue;
mu[i]=-1;
for(int j=i*2;j<=N;j+=i){
vis[j]=1;
mu[j]=-mu[j];
if(j%(i*i)==0) mu[j]=0;
}
}
for(int d=1;d<=N;d++)
for(int T=d;T<=N;T+=d)
f[T]=(f[T]+(mu[T/d]*inv[d]+mod)%mod)%mod;
for(int T=1;T<=N;T++)
for(int i=1;i<=N/T;i++)
g[T]=(g[T]+i*T*cnt[i*T])%mod;
}
signed main(){
n=read();
for(int i=1;i<=n;i++){
A[i]=read();
cnt[A[i]]++;
}
init();
int ans=0;
for(int d=1;d<=N;d++)
for(int k=1;k<=(N/d);k++)
ans=(ans+mu[k]*g[d*k]%mod*g[d*k]%mod*inv[d])%mod;
for(int i=1;i<=n;i++)
ans=(ans-A[i]+mod)%mod;
cout<<ans*inv[2]%mod;
return 0;
}