设
任何非零整数
其中
证明
唯一性仍可简化到
由于
再次应用欧几里得引理可见
对于任何素数
考虑正整数
对于任意多个正整数的
素数列
存在无穷多个素数。
证明
则
给定正整数
我们试图制造一个筛子。
我们把整数
筛完之后,筛子里剩下的就是不超过
给定正整数
对于实数
设
设
证明:根据定义,我们有
当
当
显然有
对于任意正整数
设
将
显然有
给定正整数
计算
我们需要计算的子问题形如
设
例如
设
其中
在
设
设
也就是说,对于
设
令
根据上一个命题,有
又
即
即
令
其中,
long long prime_count(long long n) {
const int k = (int) sqrt(n);
vector<long long> v; // n, n/2, n/3, ..., n
for (int i = 1; i <= k; i++)
v.push_back(n / i);
for (int i = n / (k + 1); i >= 1; i--)
v.push_back(i);
// 对于 i = 1, 2, ..., k+1 有 n/i == v[i-1]。
// 对于 i = 1, 2, ..., k 还有,i 是唯一的满足 n/d == n/i 的正整数 d。我们称这些值为大值。
const int m = (int) v.size();
vector<long long> f(m);
for (int i = 0; i < m; i++)
f[i] = v[i] - 1;
auto [p, lpf] = get_primes(k);
const int s = (int) p.size();
for (int i = 0; i < s; i++) {
f[0] -= f[p[i] - 1] - i;
if (i == s - 1) break;
const long long L = (long long) p[i] * p[i];
const int lim = k / p[i];
for (int j = p[i + 1] - 1; j < m && v[j] >= L; j++) {
if (j < k && lpf[j + 1] < p[i + 1]) continue;
if (j + 1 <= lim) {
f[j] -= f[(j + 1) * p[i] - 1] - i;
} else { // v[j] / p[i] <= k
f[j] -= f[m - v[j] / p[i]] - i;
}
}
}
return f[0];
}
时间: