题意:计算
由于数据范围达到1e10,显然直接线性筛是完成不了的,所以我们选择杜教筛。
对该式分块,令
构造,带入
,求解。
AC代码:
//#pragma comment(linker, “/STACK:1024000000,1024000000”
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e6 + 7;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const int inv2 = 5e8 + 4;
//const double pi = acos(-1.0);
const double eps = 1e-6;
const int inv = 250000002;
const int inv6 = 166666668;
int gcd(int a,int b){return b ? gcd(b,a % b) : a;}
int prime[N],cnt;
ll g[N],phi[N];
bool isprime[N];
ll n;
ll fpow(ll a,ll b)
{
ll res = 1;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
inline ll gao(ll x)
{
x %= mod;
return (x + 1) % mod * x % mod * inv2 % mod;
}
void get_phi()
{
phi[1] = 1;
for(int i = 2;i < N;++i){
if(!isprime[i]){
prime[++cnt] = i;
phi[i] = i - 1;
}
for(int j = 1;j <= cnt && i * prime[j] < N;++j)
{
isprime[i * prime[j]] = 1;
if(i % prime[j] == 0){
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
for(ll i = 1;i < N;++i) g[i] = (g[i - 1] + phi[i] % mod) % mod;
}
map<ll ,ll>mp;
ll solve(ll pos)
{
if(pos < N) return g[pos];
if(mp[pos]) return mp[pos];
ll res = gao(pos),last;
for(ll i = 2;i <= pos;i = last + 1){
last = pos / (pos / i);
res = ((res - (last - i + 1) * solve(pos / i) % mod) % mod + mod) % mod;
}
mp[pos] = res;
return res;
}
ll work(ll pos)
{
ll last,ans = 0;
for(ll i = 1;i <= pos;i = last + 1){
last = pos / (pos / i);
ans = (ans + (pos / i) % mod * ((pos / i) % mod) % mod * (solve(last) - solve(i - 1)) % mod) % mod + mod;
ans %= mod;
}
return ans;
}
int main()
{
get_phi();
scanf("%lld",&n);
printf("%lld\n",work(n));
return 0;
}