51Nod-1238 最小公倍数和V3(杜教筛)
#include<bits/stdc++.h> using namespace std; #define me(a,x) memset(a,x,sizeof(a)) #define IN freopen("in.txt","r",stdin); #define STR clock_t startTime = clock(); #define END clock_t endTime = clock();cout << double(endTime - startTime) / CLOCKS_PER_SEC *1000<< "ms" << endl; const int N=1e7+6; const int mod=1e9+7; const int inv2=mod+1>>1; const int inv6=166666668; typedef long long ll; int prime[N],tot=0; bool vis[N]={0}; ll f[N],phi[N]; void pre(){ phi[1]=1;f[0]=phi[0]=0; for(int i=2;i<N;i++){ if(!vis[i])prime[++tot]=i,phi[i]=i-1; for(int j=1;j<=tot&&i*prime[j]<N;j++){ vis[i*prime[j]]=1; if(i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; break; }else phi[i*prime[j]]=phi[i]*(prime[j]-1); } } for(int i=1;i<N;i++){ f[i]=(1LL*i*i%mod*phi[i]%mod+f[i-1])%mod; } } map<ll,ll>p; ll F(ll x){ x%=mod; x=x*(x+1)%mod*(2LL*x+1)%mod*inv6%mod; return x; } ll LR(ll x){ x%=mod; x=x*(x+1)%mod*inv2%mod; return x; } ll cal(ll n){ if(n<N)return f[n]; if(p[n])return p[n]; ll ans=LR(n);ans=ans*ans%mod; for(ll i=2,last;i<=n;i=last+1){ last=n/(n/i); ans-=1LL*(F(last)-F(i-1)+mod)%mod*cal(n/i)%mod; } return p[n]=ans; } int main(){ pre(); ll n;scanf("%lld",&n); ll ans=0; for(ll i=1,last;i<=n;i=last+1){ last=n/(n/i); ans+=1LL*(LR(last)-LR(i-1)+mod)%mod*cal(n/i)%mod; ans%=mod; } printf("%lld\n",ans); }
公式推导
#include<bits/stdc++.h> using namespace std; #define me(a,x) memset(a,x,sizeof(a)) #define IN freopen("in.txt","r",stdin); #define STR clock_t startTime = clock(); #define END clock_t endTime = clock();cout << double(endTime - startTime) / CLOCKS_PER_SEC *1000<< "ms" << endl; const int N=1e7+6; const int mod=1e9+7; const int inv2=mod+1>>1; const int inv6=166666668; typedef long long ll; int prime[N],tot=0,mu[N]; bool vis[N]={0}; ll f[N]; void pre(){ mu[1]=1;f[0]=mu[0]=0; for(int i=2;i<N;i++){ if(!vis[i])prime[++tot]=i,mu[i]=-1; for(int j=1;j<=tot&&i*prime[j]<N;j++){ vis[i*prime[j]]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; break; }else mu[i*prime[j]]=-mu[i]; } } for(int i=1;i<N;i++) for(int j=i;j<N;j+=i){ f[j]+=1LL*j*i%mod*mu[i]; f[j]=(f[j]+mod)%mod; } for(int i=1;i<N;i++)f[i]=(f[i]+f[i-1])%mod; } ll G(ll x){ x%=mod; x=x*(x+1)%mod*inv2%mod; return x; } ll F(ll x){ x%=mod; x=x*(x+1)%mod*(2LL*x+1)%mod*inv6%mod; return x; } map<ll,ll>p; ll cal(ll n){ if(n<N)return f[n]; if(p[n])return p[n]; ll ans=G(n); for(ll i=2,last;i<=n;i=last+1){ last=n/(n/i); ans-=(F(last)-F(i-1)+mod)%mod*cal(n/i); ans=(ans+mod)%mod; } return p[n]=ans; } int main(){ pre(); ll n;scanf("%lld",&n); ll ans=0; for(ll i=1,last;i<=n;i=last+1){ last=n/(n/i); ll x=G(n/i); x=x*x%mod; ans+=(cal(last)-cal(i-1)+mod)%mod*x%mod; ans%=mod; } printf("%lld\n",ans); }