[51nod1238]最小公倍数之和V3

来自FallDream的博客,未经允许,请勿转载,谢谢。

------------------------------------------------------------------------------------------

题意:求$$\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j)   \\\    n\leqslant 10^{10}$$

题解:题目即求$$\sum_{i=1}^{n}\sum_{j=1}^{n}\frac{i*j}{gcd(i,j)}$$

$$=\sum_{d=1}^{n}d*\sum_{i=1}^{\lfloor n/d\rfloor}\sum_{j=1}^{\lfloor n/d\rfloor}i*j*[gcd(i,j)=1]$$

已知$$\sum_{i=1}^{n}i*[gcd(i,n)=1]=\frac{n*\varphi(n)}{2}$$ 

所以所求即为$$\sum_{d=1}^{n}d*\sum_{i=1}^{\lfloor n/d\rfloor}i*i*\varphi(i)$$

 

$\lfloor\frac{n}{d}\rfloor$只有$\sqrt(n)$种取值,那么我们考虑快速求出$g(i)=i^{2}*\varphi(i)$的前缀和$S(i)$。

 

$$\sum_{n|d}\varphi(d)=n$$ 

$$\sum_{i=1}^{n}\sum_{d|n}\varphi(d)=\frac{n(n+1)}{2}$$

$$\sum_{i=1}^{n}\sum_{d|n}\varphi(d)*i^{2}=\frac{n^{2}*(n+1)^{2}}{4}$$

$$\sum_{i=1}^{n}\sum_{d|n}g(d)*(\frac{i}{d})^{2}=\frac{n^{2}*(n+1)^{2}}{4}$$

$$\sum_{i=1}^{n}\sum_{d=1}^{\lfloor n/i\rfloor}g(d)*i^{2}=\frac{n^{2}*(n+1)^{2}}{4}$$

$$S(i)=\frac{n^{2}*(n+1)^{2}}{4}-\sum_{i=2}^{n}i^{2}*S(\lfloor n/i\rfloor)$$

这个可以在$O\left(n^{\frac{2}{3}}\right)$时间内做完。此题得解。

-------------------------------------------------------------------

我好菜啊,推了好久.....

-----

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#define MAXN 5000000
#define ll long long
#define mod 1000000007
#define ditoly 6666666
#define inv2 500000004
#define inv4 250000002
#define inv6 166666668
using namespace std;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

struct mymap{
    ll x,ans;int next;
}e[8000000];
ll phi[MAXN+5],n,ans=0;
int s[MAXN/5],num=0,head[ditoly+5];
bool b[MAXN+5];

inline ll getcube(ll x){x%=mod;return x*(x+1)%mod*(x<<1|1)%mod*inv6%mod;}

inline void ins(ll x,ll sum)
{
    int j=x%ditoly;
    e[++num]=(mymap){x,sum,head[j]};head[j]=num;
}

inline ll getsq(ll x){x%=mod;x=x*(x+1)%mod;return x*x%mod*inv4%mod;}

ll calc(ll x)
{
    if(x<=MAXN)return phi[x];
    for(int i=head[x%ditoly];i;i=e[i].next)
        if(e[i].x==x)return e[i].ans;
    ll last,sum=getsq(x);
    for(ll i=2;i<=x;i=last+1)
    {
        last=x/(x/i);
        sum-=(getcube(last)-getcube(i-1)+mod)%mod*calc(x/i)%mod;
        while(sum<0)sum+=mod;
    }
    ins(x,sum);
    return sum;
}

int main()
{
    n=read();phi[1]=1;
    for(int i=2;i<=MAXN;i++)
    {
        if(!b[i]) phi[i]=i-1,s[++num]=i;
        for(int j=1;s[j]*i<=MAXN;j++)
        {
            b[s[j]*i]=1;
            if(i%s[j]==0){phi[s[j]*i]=phi[i]*s[j];break;}
            phi[s[j]*i]=phi[i]*(s[j]-1);
        }
    }num=0;
    for(int i=2;i<=MAXN;i++)
        phi[i]=(phi[i-1]+1LL*i*i%mod*phi[i]%mod)%mod;
    for(ll i=1,last;i<=n;i=last+1)
    {
        last=n/(n/i);ll x=(n/i)%mod;
        ans+=x*(x+1)%mod*inv2%mod*((calc(last)-calc(i-1)+mod)%mod)%mod;
        while(ans>=mod)ans-=mod;
    }
    cout<<(ans+mod)%mod;
    return 0;
}

 

posted @ 2017-03-26 14:43  FallDream  阅读(437)  评论(0编辑  收藏  举报