题解:
现在我们只要求出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
扫描二维码关注公众号,回复:
1544481 查看本文章
#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; }