洛谷 P1829 [国家集训队]Crash的数字表格 / JZPTAB 解题报告

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

题意

\(\sum\limits_{i=1}^n\sum\limits_{j=1}^mlcm(i,j)\)\(n,m\le 10^7\)


鉴于我式子没推出来,所以再推一遍。

\[\sum\limits_{i=1}^n\sum\limits_{j=1}^mlcm(i,j)\]

\[=\sum\limits_{i=1}^n\sum\limits_{j=1}^m\frac{ij}{gcd(i,j)}\]

\[=\sum\limits_{i=1}^n\sum\limits_{j=1}^m ij\sum_{k=1}^{min(i,j)}\frac{1}{k}[gcd(i,j)=k]\]

\[=\sum_{k=1}^{min(n,m)}\frac{1}{k}\sum_{i=1}^n\sum_{j=1}^mij[gcd(i,j)=k]\]

\[=\sum_{k=1}^{min(n,m)}k\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}ij[gcd(i,j)=1]\]

\[=\sum_{k=1}^{min(n,m)}k\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}ij\sum_{d=1}^{min(i,j)}\mu(d)[gcd(i,j)=d]\]

\[=\sum_{k=1}^{min(n,m)}k\sum_{d=1}^{min(\lfloor\frac{n}{k}\rfloor,\lfloor\frac{m}{k}\rfloor)}\mu(d)d^2\sum_{i=1}^{\lfloor\frac{n}{kd}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{kd}\rfloor}ij\]

令$g(x)=\frac{(x+1)x}{2}$

\[=\sum_{k=1}^{min(n,m)}k\sum_{d=1}^{min(\lfloor\frac{n}{k}\rfloor,\lfloor\frac{m}{k}\rfloor)}\mu(d)d^2g(\lfloor\frac{n}{kd}\rfloor)g(\lfloor\frac{m}{kd}\rfloor)\]

令$T=kd$

\[=\sum_{T=1}^{min(n,m)}g(\lfloor\frac{n}{T}\rfloor)g(\lfloor\frac{m}{T}\rfloor)\sum_{kd=T}kd^2\mu(d)\]

\[=\sum_{T=1}^{min(n,m)}g(\lfloor\frac{n}{T}\rfloor)g(\lfloor\frac{m}{T}\rfloor)T\sum_{d|T}d\mu(d)\]

\(f(n)=\sum_{d|n}d\mu(d)\)

研究一下\(\tt{Ta}\)的性质,设\(p\)代表一个质数。

\(f(p)=1-p,f(p^n)=f(p)\),\(f(n)\)是一个积性函数。

所以我们可以在线筛的时候把这个函数\(O(n)\)筛出来。

前面整除分块一下就可以了。

总复杂度\(O(\sqrt n+n)\)


Code:

#include <cstdio>
#define ll long long
const ll mod=20101009;
const int N=1e7;
int pri[N+10],ispri[N+10],cnt;
ll g[N+10];
#define f(x) (((x)+1)*(x)/2%mod)
void init()
{
    g[1]=1;
    for(int i=2;i<=N;i++)
    {
        if(!ispri[i])
        {
            g[i]=1-i;
            pri[++cnt]=i;
        }
        for(int j=1;j<=cnt&&pri[j]*i<=N;j++)
        {
            ispri[pri[j]*i]=1;
            if(i%pri[j]==0){g[pri[j]*i]=g[i];break;}
            else g[pri[j]*i]=g[i]*g[pri[j]]%mod;
        }
    }
    for(int i=1;i<=N;i++) g[i]*=i%=mod,(g[i]+=g[i-1])%mod;
}
ll min(ll a,ll b){return a<b?a:b;}
int main()
{
    init();
    ll ans=0,n,m;
    scanf("%lld%lld",&n,&m);
    for(ll l=1,r;l<=min(n,m);l=r+1)
    {
        r=min(n/(n/l),m/(m/l));
        (ans+=f(n/l)*f(m/l)%mod*(g[r]-g[l-1]))%=mod;
    }
    printf("%lld\n",(ans+mod)%mod);
    return 0;
}

2018.10.26

猜你喜欢

转载自www.cnblogs.com/ppprseter/p/9854278.html