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\) 的约数计算即可。
程序
#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;
}
}
}

浙公网安备 33010602011771号