[国家集训队]Crash的数字表格

Description:

求$ \sum_{i=1}^n \sum_{j=1}^m lcm(i,j) $

Hint:

$ n,m<=10^7 $

Solution:

这题有每次询问 \(O(n)\) 做法,然而原题是多组询问,所以还是好好推 \(O(\sqrt[]{n})\) 做法

首先:

\(Ans=\sum_{d=1}^{n}d * \sum_{i=1}^n \sum_{j=1}^m i * j * [gcd(i,j)==1] ​\)

$Ans=\sum_{d=1}^{n}d * \sum_{k=1}^{\lfloor \frac{n}{d} \rfloor} \mu(k) * k^2 \sum_{i=1}^{\lfloor \frac{n}{kd} \rfloor} \sum_{j=1}^{\lfloor \frac{m}{kd} \rfloor } i * j $

换元得:

\(Ans=\sum_{T=1}^{n} \sum_{i=1}^{\lfloor \frac{n}{T} \rfloor} \sum_{j=1}^{\lfloor \frac{m}{T} \rfloor } i * j * \sum_{k|T} \mu(k) * k^2 * d ​\)

$Ans=\sum_{T=1}^{n} \sum_{i=1}^{\lfloor \frac{n}{T} \rfloor} \sum_{j=1}^{\lfloor \frac{m}{T} \rfloor } i * j * (T * \sum_{k|T} \mu(k) * k) $

易知 \(g(T)=\sum_{k|T} \mu(k) * k​\) 为积性函数

前面的$ \sum_{i=1}^{\lfloor \frac{n}{T} \rfloor} \sum_{j=1}^{\lfloor \frac{m}{T} \rfloor }i * j$ 就是两个等差数列相乘

后面的线性筛处理出\(T*g(T)\)的前缀和即可


#include<bits/stdc++.h>
using namespace std;
const int mxn=1e7+5,mod=20101009;
int n,m,tot;
int p[mxn],vis[mxn];
long long g[mxn],f[mxn];

void sieve(int lim)
{
    g[1]=1;
    for(int i=2;i<=lim;++i) {
        if(!vis[i]) g[i]=1-i,p[++tot]=i;
        for(int j=1;j<=tot&&p[j]*i<=lim;++j) {
            vis[p[j]*i]=1;
            if(i%p[j]) g[p[j]*i]=g[i]*g[p[j]]%mod;
            else {g[p[j]*i]=g[i];break; }
        }
    }
    for(int i=1;i<=lim;++i) 
        f[i]=(f[i-1]+g[i]*i%mod)%mod;
}

int main()
{
    scanf("%d%d",&n,&m); int ans=0;
    sieve(10000000); if(n>m) swap(n,m); 
    for(int l=1,r;l<=n;l=r+1) {
        r=min(n/(n/l),m/(m/l)); int x=n/l,y=m/l;
        ans=(ans+1ll*(1ll*x*(x+1)/2%mod)*(1ll*y*(y+1)/2%mod)%mod*((f[r]-f[l-1]+mod)%mod)%mod)%mod;
    }
    printf("%d\n",(ans+mod)%mod);
    return 0;
}

posted @ 2019-02-17 16:06  cloud_9  阅读(115)  评论(0)    收藏  举报