题解:
现在我们只要求出g(n)就能解决此题了,ans(n)枚举因子nlogn筛一下就好了
公式秒推,分块求g(n):O(n*sqrtn*logn)秒T,尝试分块打表200*5000求g(n):还是T了
尝试OEIS才发现g(n)有递推公式g(n)=g(n-1)+d(n-1)+1,d(n)是n的因子个数,脑洞不够啊
如果是向下取整求和也有公式=sum(d(i))
g++ 405ms
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll mu[1000005];bool isp[1000005];int pri[1000005];
ll ans[1000005];ll g[1000005];ll d[1000005];
int p=0;
void init(ll n)
{
isp[1]=1;mu[1]=1;
for(ll i=2;i<=n;i++)
{
if(!isp[i])pri[++p]=i, mu[i]=-1;
for(ll j=1;j<=p&&i*pri[j]<=n;j++)
{
isp[i*pri[j]]=1;
if(i%pri[j]==0)//不互质
{
mu[i*pri[j]]=0;break;
}
else mu[i*pri[j]]=-mu[i];
}
}
}
void init2(int n)
{
for(int i=1;i<=1000000;i++)
for(int j=i;j<=1000000;j+=i)
d[j]+=1;
for(int i=1;i<=1000000;i++)g[i]=(g[i-1]+d[i-1]+1+mod)%mod;
}
int main()
{
ll n;init(1000002);init2(1000002);
for(int i=1;i<=1000000;i++)
for(int j=i;j<=1000000;j+=i)
ans[j]+=mu[i]*g[j/i]%mod;//;
for(int i=1;i<=1000000;i++)
ans[i]+=ans[i-1]%mod;
while(~scanf("%lld",&n))
cout<<(ans[n]+mod)%mod<<endl;
}