我不明白这题为什么要莫比乌斯反演
题意
求 (sum_{i< j}operatorname{lcm}left(a_i,a_j ight)),且 (a_ile10^6)。
解答
令
[egin{aligned}
fleft(x
ight)&=sum_{i=1}^nsum_{j=i+1}^{n}a_ia_jleft[x mid gcdleft(a_i,a_j
ight)
ight]\
&=sum_{i=1}^nsum_{j=i+1}^{n}left(a_ileft[xmid a_i
ight]
ight)left(a_jleft[xmid a_j
ight]
ight) \
&=dfrac{1}{2}cdotleft(left(sum_{xmid i}^{n}a_i
ight)^2-sum_{xmid i}^{n}a_i^2
ight) \
gleft(x
ight)&=sum_{i=1}^nsum_{j=i+1}^{n}a_ia_jleft[ gcdleft(a_i,a_j
ight)=x
ight] \
&=sum_{i=1}^nsum_{j=i+1}^{n}a_ia_jleft[x mid gcdleft(a_i,a_j
ight)
ight]-sum_{k>x,xmid k}^Asum_{i=1}^nsum_{j=i+1}^{n}a_ia_jleft[gcdleft(a_i,a_j
ight)=k
ight] \
&=fleft(x
ight)-sum_{k>x,xmid k}^Agleft(k
ight)
end{aligned}
]
则从小到大枚举 (x) 即可计算出所有的 (f),(g),时间复杂度为 (sum_{i=1}^Adfrac{A}{i}+mathcal{O}left(n ight)=mathcal{O}left(Aln A+n ight)),答案为
[egin{aligned}
sum_{i=1}^nsum_{j=i+1}^{n}operatorname{lcm}left(a_i,a_j
ight)&=sum_{i=1}^nsum_{j=i+1}^{n}dfrac{a_ia_j}{gcdleft(a_i,a_j
ight)}\
&=sum_{dge1}sum_{i=1}^nsum_{j=i+1}^{n}dfrac{a_ia_j}{d}left[gcdleft(a_i,a_j
ight)=d
ight]\
&=sum_{dge1}dfrac{gleft(x
ight)}{d}
end{aligned}
]
代码
#include <algorithm>
using namespace std;
typedef long long ll;
constexpr int N=200010,K=1000010,p=998244353;
int inv[K],sum[K],a[N],n,cnt[K];
int main(){
scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%d",&a[i]),++cnt[a[i]];
inv[1]=1;for(int i=2;i<K;++i) inv[i]=1ll*(p-p/i)*inv[p%i]%p;
int ans=0;
for(int i=K-1;i;--i){
int s1=0,s2=0;
for(int j=i;j<K;j+=i) s1=(s1+1ll*cnt[j]*j%p)%p,s2=(s2+1ll*cnt[j]*j%p*j%p)%p;
sum[i]=1ll*(1ll*s1*s1%p-s2+p)*inv[2]%p;
for(int j=(i<<1);j<K;j+=i) sum[i]=(sum[i]-sum[j]+p)%p;
// if(i<10) printf("%d %d %d %d %d
",i,sum[i],s1,s2,inv[i]);
ans=(ans+1ll*inv[i]*sum[i]%p)%p;
}
printf("%d
",ans);
return 0;
}