RT,大概炸 long long 了?找不到...
#include<bits/stdc++.h>
#define re register
#define N 201001
#define MAX 2001
#define inf 1e18
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=1000000007,inv3=333333336;
inline void read(re ll &ret)
{
ret=0;re bool pd=false;re char c=getchar();
while(!isdigit(c)){pd|=c=='-';c=getchar();}
while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c&15);c=getchar();}
ret=pd?-ret:ret;
return;
}
ll n;
bool prime[N];
ll p[N],tot,sp[2][N],g[2][N],ind[2][N],w[N],cnt;
inline void init(re ll n)
{
for(re ll i=2;i*i<=n;i++)
prime[i]=true;
for(re ll i=2;i*i<=n;i++)
{
if(prime[i])
p[++tot]=i,sp[0][tot]=(sp[0][tot-1]+p[tot])%mod,sp[1][tot]=(sp[1][tot-1]+p[tot]*p[tot]%mod)%mod;
for(re ll j=1;j<=tot&&p[j]*i*p[j]*i<=n;j++)
{
prime[p[j]*i]=false;
if(!(i%p[j]))
break;
}
}
return;
}
inline ll s(re ll x,re ll j)
{
if(p[j]>=x)
return 0;
re ll k=(n/x>=x)?ind[0][x]:ind[1][n/x];
re ll ans=(g[1][k]-g[0][k])%mod-(sp[1][j]-sp[0][j])%mod;
ans=(ans+mod)%mod;
for(re ll i=j+1;i<=tot&&p[i]*p[i]<=x;i++)
for(re ll tmp=1,num=p[i];num<=x;tmp++,num*=p[i])
ans+=num%mod*(num-1)%mod*(s(x/num,i)+(tmp!=1))%mod,ans%=mod;
ans=(ans+mod)%mod;
return ans;
}
signed main()
{
read(n);
init(n);
for(re ll i=1,j;i<=n;i=j+1)
{
j=n/(n/i);
w[++cnt]=n/i;
if(n/w[cnt]>=w[cnt])
ind[0][w[cnt]]=cnt;
else
ind[1][n/w[cnt]]=cnt;
g[0][cnt]=w[cnt]%mod;
g[1][cnt]=g[0][cnt]*(g[0][cnt]+1)/2%mod*((g[0][cnt]<<1)+1)%mod*inv3%mod;
g[1][cnt]=(g[1][cnt]-1+mod)%mod;
g[0][cnt]=((g[0][cnt]+1)*g[0][cnt]/2-1)%mod;
}
for(re ll i=1;i<=tot;i++)
{
for(re ll j=1;j<=cnt&&p[i]*p[i]<=w[j];j++)
{
re ll tmp=w[j]/p[i];
re ll k=(n/tmp>=tmp)?ind[0][tmp]:ind[1][n/tmp];
g[0][j]-=p[i]*(g[0][k]-sp[0][i-1]+mod)%mod;
g[1][j]-=p[i]*p[i]%mod*(g[1][k]-sp[1][i-1]+mod)%mod;
g[0][j]=(g[0][j]+mod)%mod;
g[1][j]=(g[1][j]+mod)%mod;
}
}
printf("%lld\n",(s(n,0)+1)%mod);
exit(0);
}