51nod1227 平均最小公倍数

题目
题解

Code

#include
using namespace std;
const int N=4000002,inv2=500000004,inv6=166666668,M=1e9+7;
int a,b,v[255],i,j,cnt,phi[N],pr[N/13],nn,t;
bool vis[N];
int sum(int n){
	if (n<N) return phi[n];
	if (v[nn/n]) return v[nn/n];
	int ans=1ll*n*(n+1)%M*(n*2+1)%M*inv6%M;
	for (int i=2,j;i<=n;i=j+1){
		j=n/(n/i);
		(ans-=1ll*(j-i+1)*(i+j)%M*inv2%M*sum(n/i)%M)%=M;
	}
	return v[nn/n]=ans;
}
int F(int n){
	nn=n,memset(v,0,sizeof(v));
	int ans=0;
	for (int i=1,j;i<=n;i=j+1){
		j=n/(n/i);
		(ans+=1ll*(sum(j)-sum(i-1))*(n/i)%M)%=M;
	}
	return (1ll*(ans+n)*inv2%M+M)%M;
}
int main(){
	scanf("%d%d",&a,&b);
	phi[1]=1;
	for (i=2;i<N;i++){
		if (!vis[i]) pr[cnt++]=i,phi[i]=i-1;
		for (j=0;j<cnt && (t=i*pr[j])<N;j++){
			vis[t]=1;
			if (!(i%pr[j])){
				phi[t]=phi[i]*pr[j];
				break;
			}
			phi[t]=phi[i]*(pr[j]-1);
		}
	}
	for (i=2;i<N;i++) phi[i]=1ll*phi[i]*i%M,(phi[i]+=phi[i-1])%=M;
	printf("%d",(F(b)-F(a-1)+M)%M);
}

你可能感兴趣的:(数学,杜教筛)