BZOJ4916: 神犇和蒟蒻 杜教筛
#include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define ll long long #define maxn 10000005 using namespace std; const long long mod=1000000007; map<int,ll>getf; int cnt; int vis[maxn]; int prime[maxn]; ll phi[maxn]; ll sumf[maxn]; ll rev6; int N; inline ll qpow(ll base,ll k) { ll tmp=1; while(k) { if(k&1) tmp=tmp*base%mod; base=base*base%mod; k>>=1; } return tmp; } inline void prepare() { rev6=qpow(1ll*6, mod-2); phi[1]=1; for(int i=2;i<=N;++i) { if(!vis[i]) prime[++cnt]=i, phi[i]=i-1; for(int j=1;j<=cnt&&1ll*i*prime[j]<=N;++j) { vis[i*prime[j]]=1; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } for(int i=1;i<=N;++i) sumf[i]=(sumf[i-1]+1ll*phi[i]*i%mod)%mod; } ll Sum(ll n) { return (n*(n+1)%mod*(n+n+1))%mod*rev6%mod; } ll Get(int n) { if(n<=N) return sumf[n]; if(getf[n]) return getf[n]; ll re=Sum(n), tmp; int i,j; for(i=2;i<=n;i=j+1) { j=n/(n/i); tmp=1ll*(i+j)*(j-i+1)/2%mod; tmp=(tmp*Get(n/i))%mod; tmp%=mod; re=(re-tmp+mod)%mod; } return getf[n]=re; } int main() { // setIO("input"); int n; scanf("%d",&n); N=min(10000002,n); prepare(); printf("%d %lld\n",1,Get(n)); return 0; }