SP11345 lcm addition

Luogu 链接
SPOJ 链接
Virtual Judge 链接

题意

题目描述

给定 \(a,b\),求:

\[\sum_{i=a}^b\operatorname{lcm}(i,b) \]

因为输出可能非常大,所以结果取模 \(10^9+7\)


输入格式

多测,第一行一个正整数 \(T\)\(T\le10^5\)),代表组数。
每组数据一行两个正整数 \(a\)\(b\)\(1\le a\le b\le10^6\)),含义见题目描述


输出格式

题目描述

思路

\(\displaystyle F(n,m)=\sum_{i=1}^n\operatorname{lcm}(i,m)\),则原式即为 \(F(b,b)-F(a-1,b)\)

\[\begin{aligned} F(n,m) &=\sum_{i=1}^n\operatorname{lcm}(i,m)\\ &=m\sum_{i=1}^n\dfrac{i}{\gcd(i,m)}\\ &=m\sum_{d\mid m}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}[\gcd(i,\dfrac{m}{d})=1]i\\ &=m\sum_{d\mid m}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}i\sum_{t\mid i,t\mid\frac{m}{d}}\mu(t)\\ &=m\sum_{T\mid m}\sum_{t\mid T}\mu(t)t\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}i\\ &=m\sum_{T\mid m}S(\lfloor\dfrac{n}{T}\rfloor)\sum_{t\mid T}\mu(t)t\\ &=m\sum_{T\mid m}S(\lfloor\dfrac{n}{T}\rfloor)f(T) \end{aligned}\]

考虑线性筛 \(f\)。(可参考我的这篇文章

注意到 \(f(p^k)=1-p\),所以:

  • \(x\bmod p=0\) 时:\(f(px)=f(x)\)
  • 否则:\(f(px)=f(x)f(p)\)

询问时,枚举 \(m\) 的约数计算即可。

程序

AC 记录

#include<bits/stdc++.h>
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forUP(i,a,b) for(int i=(a);i<(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
#define forG(i,u,v) for(int i=head[u],v=to[i];i;i=nxt[i],v=to[i])
#define pb emplace_back
using ll=long long;using ull=unsigned long long;using uint=unsigned int;using db=double;using ld=long db;using pii=std::pair<int,int>;using pdi=std::pair<db,int>;using vl=__int128;using uvl=unsigned __int128;
constexpr int INF=0x3f3f3f3f,MINF=0xcfcfcfcf;constexpr long long INFLL=0x3f3f3f3f3f3f3f3f,MINFLL=0xcfcfcfcfcfcfcfcf;constexpr double INFDB=1e50,eps=1e-9;
template<class _Tp>void chkMax(_Tp &x,const _Tp &y){x<y?x=y:0;}template<class _Tp>void chkMin(_Tp &x,const _Tp &y){x>y?x=y:0;}
constexpr int N=1e6+10,mod=1e9+7;int __test_num=1,__test_id;using namespace std;void __init();

int a,b,cnt,P[N],f[N];bool np[N];

int S(int n){return 1ll*n*(n+1)/2%mod;}

int F(int n,int m){
	int ans=0;
	for(int i=1;i*i<=m;++i)if(m%i==0){
		(ans+=1ll*S(n/i)*f[i]%mod)%=mod;
		if(i*i!=m)(ans+=1ll*S(n/(m/i))*f[m/i]%mod)%=mod;
	}
	ans=1ll*ans*m%mod;
	return ans;
}

void __solve(int __test_id){
	scanf("%d%d",&a,&b);
	printf("%d\n",(F(b,b)-F(a-1,b)+mod)%mod);
}
int main(){
	__init();
	forUp(i,1,__test_num)__solve(i);
	return 0;
}
void __init(){
	//const string __file_name="test";freopen((__file_name+".in").c_str(),"r",stdin);freopen((__file_name+".out").c_str(),"w",stdout);
	scanf("%d",&__test_num);
	f[1]=1;
	int n=N-10;
	forUp(i,2,n){
		if(!np[i])P[++cnt]=i,f[i]=mod+1-i;
		for(int j=1;j<=cnt&&i*P[j]<=n;++j){
			np[i*P[j]]=true;
			if(i%P[j]==0){
				f[i*P[j]]=f[i];
				break;
			}
			f[i*P[j]]=1ll*f[i]*f[P[j]]%mod;
		}
	}
}
posted @ 2025-07-29 16:36  LXcjh4998  阅读(30)  评论(0)    收藏  举报