太阳神 [莫比乌斯反演]_#include

比较容易想到,先将 > n 转换成 <= n

太阳神 [莫比乌斯反演]_c++_02

然后就可以直接暴力枚举 l,然后快速计算 (d, i, j) 的对数

不妨设 d <= i <= j,然后 d 只需要枚举到 太阳神 [莫比乌斯反演]_i++_03, i 从 d 开始枚举到 太阳神 [莫比乌斯反演]_i++_04, 就可以暴力怼过


#include<bits/stdc++.h>
#define N 100050
using namespace std;
typedef long long ll;
const int Mod = 1000000007;
ll n;
int prim[N], isp[N], mu[N], tot;
void prework(){
mu[1] = 1;
for(int i = 2; i <= N-50; i++){
if(!isp[i]) prim[++tot] = i, mu[i] = -1;
for(int j = 1; j <= tot; j++){
if(i * prim[j] > N-50) break;
isp[i * prim[j]] = 1;
if(i % prim[j] == 0){ mu[i * prim[j]] = 0; break;}
mu[i * prim[j]] = mu[i] * mu[prim[j]];
}
}
}
int main(){
scanf("%lld", &n); prework();
ll x = n % Mod, ans = (x * x) % Mod;
for(ll i = 1; i * i <= n; i++){
if(!mu[i]) continue;
ll m = n / i / i, sum = 0;
for(ll a = 1; a * a * a <= m; a++){
for(ll b = a; a * b * b <= m; b++){
ll c = m / a / b - b + 1;
if(a == b) sum = (sum + 1 + (c - 1) * 3) % Mod;
else sum = (sum + 3 + (c - 1) * 6) % Mod;
}
} ans = (ans - mu[i] * sum) % Mod;
} cout << (ans % Mod + Mod) % Mod;
return 0;
}