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

传送门

先从一道简单题入手 (LCM sum)

求 

\sum_{i=1}^nlcm(i,n)

=n\sum_{d|n}\sum_{i=1}^ni/d[gcd(i,n)=d]

令k=i/d

=n\sum_{d|n}\sum_{k=1}^{n/d}k[gcd(kd,n)=d]

gcd里面同除d

=n\sum_{d|n}\sum_{k=1}^{n/d}k[gcd(k,n/d)=1]

我们发现枚举到n/d 与 d是等价的

=n\sum_{d|n}\sum_{k=1}^{d}k[gcd(k,d)=1]

=n\sum_{d|n}\varphi(d)d+[d=1]/2


这道题就可以转化为

Ans=2\sum_{i=1}^n\sum_{j=1}^ilcm(i,j)-\sum_{i=1}^ni

=2\sum_{i=1}^n(i/2\sum_{d|i}\dvarphi(d)+[d=1])-\sum_{i=1}^ni

=\sum_{d=1}^nd\varphi(d)\sum_{i=1}^{n/d}id=\sum_{d=1}^nd^2\varphi(d)\sum_{i=1}^{n/d}i

杜教筛筛第一坨, 然后整除分块


#include<bits/stdc++.h>
#define N 1000050
#define LL long long
#define Mod 1000000007
#define inv2 500000004
#define inv6 166666668
using namespace std;
int prim[N], isp[N], tot, phi[N];
LL val[N],n;
map<LL,LL> F; 
void prework(){
	phi[1] = val[1] = 1;
	for(int i=2;i<=N-50;i++){
		if(!isp[i]) prim[++tot] = i, phi[i] = i-1;
		for(int j=1;j<=tot;j++){
			if(i*prim[j] > N-50) break;
			isp[i*prim[j]] = 1;
			if(i%prim[j] == 0){
				phi[i*prim[j]] = phi[i] * prim[j];
				break;
			}
			phi[i*prim[j]] = phi[i] * (prim[j] - 1);
		}
	}
	for(int i=2;i<=N-50;i++) val[i] = (LL)phi[i] * i % Mod * i % Mod;
	for(int i=2;i<=N-50;i++) val[i] = (val[i] + val[i-1]) % Mod;
} 
LL Sum(LL x){ x %= Mod; return x * (x+1) % Mod * inv2 % Mod;}
LL calc(LL x){ x %= Mod; return x * (x+1) % Mod * ((x*2+1) % Mod) % Mod * inv6 % Mod;}
LL getf(LL x){
	if(x<=N-50) return val[x];
	if(F[x]) return F[x];
	LL ans = Sum(x); ans = (ans * ans) % Mod;
	for(LL l=2,r;l<=x;l=r+1){
		LL v = x/l; r = x/v;
		ans -= (calc(r) - calc(l-1)) * getf(v) % Mod;
		ans = (ans % Mod + Mod) % Mod;
	} return F[x] = ans;
}
int main(){
	prework(); scanf("%lld",&n); LL ans = 0;
	for(LL l=1,r;l<=n;l=r+1){
		LL v = n/l; r = n/v;
		ans += Sum(v) * (getf(r) - getf(l-1)) % Mod;
		ans = (ans % Mod + Mod) % Mod;
	} printf("%lld",ans); return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值