题意:
求 ∑ i = 1 n ∑ j = 1 n l c m ( i , j ) m o d 1 0 9 ​ + ​ 7 n < = 1 0 10 \sum_{i=1}^n\sum_{j=1}^nlcm(i,j) ~~~~~~~~mod~10^9\!+\!7\\n<=10^{10} i=1∑nj=1∑nlcm(i,j) mod 109+7n<=1010
题目分析:
化简,
∑
i
=
1
n
∑
j
=
1
n
l
c
m
(
i
,
j
)
=
∑
i
=
1
n
∑
j
=
1
n
i
∗
j
g
c
d
(
i
,
j
)
\sum_{i=1}^n\sum_{j=1}^nlcm(i,j)\\=\sum_{i=1}^n\sum_{j=1}^n\frac {i*j}{gcd(i,j)}
i=1∑nj=1∑nlcm(i,j)=i=1∑nj=1∑ngcd(i,j)i∗j
枚举gcd
=
∑
d
=
1
n
d
∗
∑
i
=
1
n
d
∑
j
=
1
n
d
[
g
c
d
(
i
,
j
)
=
=
1
]
∗
i
∗
j
=\sum_{d=1}^nd*\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac nd}[gcd(i,j)==1]*i*j
=d=1∑nd∗i=1∑dnj=1∑dn[gcd(i,j)==1]∗i∗j
OK,且慢,这里的gcd(i,j)==1就很讲究了,有两种方法
法一:欧拉函数 φ \varphi φ
因为
∑
i
=
1
n
d
∑
j
=
1
n
d
\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac nd}
∑i=1dn∑j=1dn是对称的,所以可以化为
=
∑
d
=
1
n
d
∗
{
(
2
∑
i
=
1
n
d
i
∑
j
=
1
i
j
[
(
i
,
j
)
=
=
1
]
)
−
1
}
=
∑
d
=
1
n
d
∗
{
(
2
∑
i
=
1
n
d
i
∗
i
∗
φ
(
i
)
+
[
i
=
1
]
2
)
−
1
}
=
∑
d
=
1
n
d
∗
∑
i
=
1
n
d
i
2
∗
φ
(
i
)
=\sum_{d=1}^nd*\left\{\left(2\sum_{i=1}^{\frac nd}i\sum_{j=1}^ij[(i,j)==1]\right)-1\right\}\\=\sum_{d=1}^nd*\left\{\left(2\sum_{i=1}^{\frac nd}i*\frac{i*\varphi(i)+[i=1]}2\right)-1\right\}\\=\sum_{d=1}^nd*\sum_{i=1}^{\frac nd}i^2*\varphi(i)
=d=1∑nd∗⎩⎨⎧⎝⎛2i=1∑dnij=1∑ij[(i,j)==1]⎠⎞−1⎭⎬⎫=d=1∑nd∗⎩⎨⎧⎝⎛2i=1∑dni∗2i∗φ(i)+[i=1]⎠⎞−1⎭⎬⎫=d=1∑nd∗i=1∑dni2∗φ(i)
然后按照d分块优化,要求
i
2
∗
φ
(
i
)
i^2*\varphi(i)
i2∗φ(i)的前缀和,把它看做
i
d
⋅
i
d
⋅
φ
id\cdot id\cdot\varphi
id⋅id⋅φ
那么
(
i
d
⋅
i
d
⋅
φ
)
∗
(
i
d
⋅
i
d
)
=
(id\cdot id\cdot\varphi)*(id\cdot id)=
(id⋅id⋅φ)∗(id⋅id)=
∑
i
∣
n
i
2
∗
φ
(
i
)
∗
(
n
i
)
2
=
n
2
∑
i
∣
n
φ
(
i
)
=
n
3
=
i
d
3
\sum_{i|n}i^2*\varphi(i)*(\frac ni)^2\\=n^2\sum_{i|n}\varphi(i)\\=n^3\\=id^3
i∣n∑i2∗φ(i)∗(in)2=n2i∣n∑φ(i)=n3=id3
i
d
2
和
i
d
3
id^2和id^3
id2和id3的前缀和都很好求,所以问题就解决了
∑
i
=
1
n
i
3
=
∑
i
=
1
n
∑
d
∣
i
d
2
∗
φ
(
d
)
∗
(
i
d
)
2
=
∑
i
=
1
n
i
2
∑
d
=
1
n
i
d
2
∗
φ
(
d
)
=
∑
i
=
1
n
i
2
∗
F
(
n
i
)
\sum_{i=1}^ni^3=\sum_{i=1}^n\sum_{d|i}d^2*\varphi(d)*(\frac id)^2\\=\sum_{i=1}^ni^2\sum_{d=1}^{\frac ni}d^2*\varphi(d)\\=\sum_{i=1}^ni^2*F(\frac ni)
i=1∑ni3=i=1∑nd∣i∑d2∗φ(d)∗(di)2=i=1∑ni2d=1∑ind2∗φ(d)=i=1∑ni2∗F(in)
把i=1提出来,那么
F
(
n
)
=
∑
i
=
1
n
i
3
−
∑
i
=
2
n
i
2
∗
F
(
n
i
)
F(n)=\sum_{i=1}^ni^3-\sum_{i=2}^ni^2*F(\frac ni)
F(n)=i=1∑ni3−i=2∑ni2∗F(in)
i
2
∗
φ
(
i
)
i^2*\varphi(i)
i2∗φ(i)是积性函数,可以线性筛一部分,然后分块优化递归求解即可
法一的核心点: ∑ i = 1 n i ∗ [ ( n , i ) = = 1 ] = n ∗ φ ( n ) + [ n = 1 ] 2 \sum_{i=1}^ni*[(n,i)==1]={n*\varphi(n)+[n=1]\over2} i=1∑ni∗[(n,i)==1]=2n∗φ(n)+[n=1]
因为倘若i与n互质,则n-i也与n互质,这样的对数有 φ ( n ) / 2 \varphi(n)/2 φ(n)/2对,每对的和都为n
法二:莫比乌斯反演 μ \mu μ
∑
d
=
1
n
d
∗
∑
i
=
1
n
d
∑
j
=
1
n
d
[
g
c
d
(
i
,
j
)
=
=
1
]
∗
i
∗
j
=
∑
d
=
1
n
d
∗
∑
i
=
1
n
d
∑
j
=
1
n
d
i
∗
j
∗
∑
k
∣
(
i
,
j
)
μ
(
k
)
=
∑
d
=
1
n
d
∗
∑
k
=
1
n
d
μ
(
k
)
k
2
∑
i
=
1
n
d
k
∑
j
=
1
n
d
k
i
∗
j
\sum_{d=1}^nd*\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac nd}[gcd(i,j)==1]*i*j\\=\sum_{d=1}^nd*\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac nd}i*j*\sum_{k|(i,j)}\mu(k)\\=\sum_{d=1}^nd*\sum_{k=1}^{\frac nd}\mu(k)k^2\sum_{i=1}^{\frac n{dk}}\sum_{j=1}^{\frac n{dk}}i*j
d=1∑nd∗i=1∑dnj=1∑dn[gcd(i,j)==1]∗i∗j=d=1∑nd∗i=1∑dnj=1∑dni∗j∗k∣(i,j)∑μ(k)=d=1∑nd∗k=1∑dnμ(k)k2i=1∑dknj=1∑dkni∗j
令dk=T
=
∑
T
=
1
n
(
n
T
∗
(
n
T
+
1
)
2
)
2
∗
∑
k
∣
T
μ
(
k
)
∗
k
2
∗
T
k
\large=\sum_{T=1}^n({\frac nT*(\frac nT+1)\over2})^2*\sum_{k|T}\mu(k)*k^2*{\frac Tk}
=T=1∑n(2Tn∗(Tn+1))2∗k∣T∑μ(k)∗k2∗kT
按照T分块优化,要求
∑
k
∣
T
μ
(
k
)
∗
k
2
∗
T
k
\sum_{k|T}\mu(k)*k^2*{\frac Tk}
∑k∣Tμ(k)∗k2∗kT的前缀和(这时候最好不要把T提出去),把它看做
(
i
d
⋅
i
d
⋅
μ
)
∗
i
d
(id\cdot id\cdot\mu)*id
(id⋅id⋅μ)∗id
那么
(
i
d
⋅
i
d
⋅
μ
)
∗
i
d
∗
(
i
d
⋅
i
d
)
=
(id\cdot id\cdot\mu)*id*(id\cdot id)=
(id⋅id⋅μ)∗id∗(id⋅id)=
(
i
d
⋅
i
d
⋅
μ
)
∗
(
i
d
⋅
i
d
)
∗
i
d
=
(
∑
d
∣
T
d
2
∗
μ
(
d
)
∗
(
T
d
)
2
)
∗
i
d
=
(
T
2
∑
d
∣
T
μ
(
d
)
)
∗
i
d
=
∑
T
∣
N
T
2
∗
(
N
T
)
∑
d
∣
T
μ
(
d
)
=
N
∑
T
∣
N
T
[
T
=
=
1
]
=
i
d
(id\cdot id\cdot\mu)*(id\cdot id)*id\\=\left(\sum_{d|T}d^2*\mu(d)*(\frac Td)^2\right)*id\\=\left(T^2\sum_{d|T}\mu(d)\right)*id\\=\sum_{T|N}T^2*(\frac NT)\sum_{d|T}\mu(d)\\=N\sum_{T|N}T[T==1]\\=id
(id⋅id⋅μ)∗(id⋅id)∗id=⎝⎛d∣T∑d2∗μ(d)∗(dT)2⎠⎞∗id=⎝⎛T2d∣T∑μ(d)⎠⎞∗id=T∣N∑T2∗(TN)d∣T∑μ(d)=NT∣N∑T[T==1]=id
i
d
2
和
i
d
id^2和id
id2和id的前缀和都很好求,剩下的部分就和法一的转化方法类似了
法二的核心: [ n = = 1 ] = ∑ d ∣ n μ ( d ) [n==1]=\sum_{d|n}\mu(d) [n==1]=d∣n∑μ(d)
两种方法的共同点:
都利用了卷积(递归方法)来求解n比较大时,通常n<=1e9,1e10,1e11,的前缀和问题,构造出 f ∗ g = h f*g=h f∗g=h的形式,当g,h的前缀和可以O(1)求解,且f为积性函数,可以线性筛一部分时,求解f的前缀和的时间复杂度为 O ( n 2 3 ) O(n^{\frac 23}) O(n32)
Ps:两种方法都试图通过卷积消去 φ \varphi φ或 μ \mu μ前面的系数,从而简化形式,这是个初学时很难想到的点(至少我没想到。。。)。
此处贴出法一的代码,法二请读者自行尝试。。。
#include<cstdio>
#include<map>
#define LL long long
using namespace std;
const int mod = 1e9+7, N = 5000000, inv2 = 5e8+4, inv6 = 166666668;
int p[N/10],sum[N+5];
bool v[N+5];
map<LL,int>F;
inline int sqr(int x){return 1ll*x*x%mod;}
void Prime()
{
sum[1]=1;int cnt=0;
for(int i=2;i<=N;i++)
{
if(!v[i]) p[++cnt]=i,sum[i]=1ll*i*i%mod*(i-1)%mod;
for(int j=1,k;j<=cnt&&p[j]*i<=N;j++)
{
v[k=p[j]*i]=1;
if(i%p[j]==0) {sum[k]=1ll*sum[i]*p[j]%mod*sqr(p[j])%mod;break;}
sum[k]=1ll*sum[i]*sum[p[j]]%mod;
}
}
for(int i=2;i<=N;i++) sum[i]=(sum[i]+sum[i-1])%mod;
}
inline LL calc(LL n){return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;}
int solve(LL n)
{
if(n<=N) return sum[n];
if(F.count(n)) return F[n];
int ret=sqr(n%mod*((n+1)%mod)%mod*inv2%mod);
for(LL i=2,j;i<=n;i=j+1)
{
j=n/(n/i);
ret=(ret-(calc(j%mod)-calc((i-1)%mod))*solve(n/i))%mod;
}
return F[n]=ret;
}
int main()
{
Prime();
LL n,ans=0;
scanf("%lld",&n);
for(LL i=1,j;i<=n;i=j+1)
{
j=n/(n/i);
ans=(ans+(i+j)%mod*(j-i+1)%mod*inv2%mod*solve(n/i))%mod;
}
printf("%lld",(ans+mod)%mod);
}