题目
设 (large A(n)=frac{1}{n}sum_{i=1}^n lcm(i,n)),
求 (sum_{i=l}^rA(i)),(nleq 10^9)
分析
题意可以转化成求 (large sum_{i=1}^nfrac{1}{i}sum_{j=1}^i lcm(i,j))
首先把 (lcm) 弄掉就是 (large sum_{i=1}^nsum_{j=1}^ifrac{j}{gcd(i,j)})
考虑枚举 (gcd(i,j)) 那么再化简一下可以得到
[sum_{i=1}^nsum_{d|i}sum_{j=1}^{frac{i}{d}}j[gcd(frac{i}{d},j)==1]=sum_{i=1}^nsum_{d|i}sum_{j=1}^{d}j[gcd(d,j)==1]
]
设 (large f(n)=sum_{i=1}^{n}j[gcd(n,i)==1]),那么 (large f(n)=egin{cases}frac{nvarphi(n)}{2}[n>1]\1end{cases})
那么原式进一步化简为 (large frac{n}{2}+frac{1}{2}sum_{i=1}^nsum_{d|i}dvarphi(d))
枚举 (d) 可以得到
[frac{n}{2}+frac{1}{2}sum_{d=1}^ndvarphi(d)lfloorfrac{n}{d}
floor
]
外层整除分块,然后里层卷一个 (id) 杜教筛就可以了
代码
#include <cstdio>
#include <unordered_map>
using namespace std;
const int N=10000011,mod=1000000007;
const long long i2=(mod+1)/2,i6=i2/3;
int f[N],prime[N],v[N],Cnt,A,B;
unordered_map<int,int>F;
int mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
void Pro(int n){
f[1]=v[1]=1;
for (int i=2;i<=n;++i){
if (!v[i]) prime[++Cnt]=v[i]=i,f[i]=i*(i-1ll)%mod;
for (int j=1;j<=Cnt&&prime[j]<=n/i;++j){
f[i*prime[j]]=1ll*f[i]*f[prime[j]]%mod,v[i*prime[j]]=1;
if (i%prime[j]==0){
f[i*prime[j]]=mo(f[i*prime[j]],1ll*f[i]*prime[j]%mod);
break;
}
}
}
for (int i=2;i<=n;++i) f[i]=mo(f[i],f[i-1]);
}
int phid(int n){
if (n<=N-11) return f[n];
if (F.find(n)!=F.end()) return F[n];
int ans=i6*n%mod*(n+1)%mod*(n<<1|1)%mod;
for (int l=2,r;l<=n;l=r+1)
r=n/(n/l),ans=mo(ans,mod-i2*(l+r)%mod*(r-l+1)%mod*phid(n/l)%mod);
return ans;
}
int answ(int n){
int ans=n,las=0;
for (int l=1,r,now;l<=n;l=r+1,las=now){
r=n/(n/l),now=phid(r);
ans=mo(ans,1ll*(now-las+mod)*(n/l)%mod);
}
return i2*ans%mod;
}
int main(){
Pro(N-11),scanf("%d%d",&A,&B);
return !printf("%d",mo(answ(B),mod-answ(A-1)));
}