[题解] AGC038C

我不明白这题为什么要莫比乌斯反演

题意

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

原文地址:https://www.cnblogs.com/aixiaoyaowudi/p/15412447.html