题解:P5946 [POI 2002] B-Smooth 数
差分转化为求
记忆化搜索。先预处理出所有
注意剪枝:如果
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000005;
int l, r, p, np[N];
vector<int> pr;
unordered_map<int, int> mem;
void init(int n) {
for (int i = 2; i <= n; i++) {
if (!np[i])
pr.push_back(i);
for (int j : pr) {
if (i * j > n) break;
np[i * j] = 1;
if (i % j == 0) break;
}
}
}
int count_primes(int x, int i) {
int l = i, r = pr.size() - 1, ans = i;
while (l <= r) {
int mid = (l + r) >> 1;
if (pr[mid] <= x) l = mid + 1, ans = mid;
else r = mid - 1;
}
return ans - i + 1;
}
int dfs(int x, int i = 0) {
if (x < 1) return 0;
if (i >= pr.size() || pr[i] > x) return 1;
if (pr[i] * pr[i] > x) return count_primes(x, i) + 1;
int id = x * pr.size() + i;
if (mem.count(id)) return mem[id];
return mem[id] = dfs(x, i + 1) + dfs(x / pr[i], i);
}
signed main() {
cin >> l >> r >> p;
r += l;
init(p);
cout << dfs(r) - dfs(l - 1) << endl;
return 0;
}