登录—专业IT笔试面试备考平台_牛客网
题意
思路
考虑离线Bit做法
这种离线Bit,一般都是去考虑二维数点就能写清楚了
确定好两维:x 轴是1 ~ n, y 轴是 k 的大小
然后去遍历值域,如果值域很大的话需要排序+离散化,但是这里不需要
这里有个容易想错的点,对于 Bit 维护的 y 轴,query(x)维护的是 y 轴上 <= x 的值,也就是说,query是个 y 轴上的前缀和
query(x)是个前缀和,它不是 y轴 上某个数的值
这样就直接写就好了,注意询问需要用 vector 存,否则会出错
#include <bits/stdc++.h>#define int long long
#define lowbit(x) (x & (-x))constexpr int N = 3e6 + 10;
constexpr int M = 1e4 + 10;
constexpr int mod = 998244353;
constexpr int Inf = 0x3f3f3f3f;std::vector<std::pair<int, int> > V[N];int len = 0;
int prime[N], vis[N], minp[N];
int n[N], k[N];
int id[N];
int ans[N];
int tr[N];void P_init(int n) {for (int i = 2; i <= n; i ++) {if (!vis[i]) {minp[i] = i;prime[++len] = i;}for (int j = 1; i <= n / prime[j]; j ++) {vis[i * prime[j]] = 1;minp[i * prime[j]] = prime[j];if (i % prime[j] == 0) {break;}}}
}
void add(int x, int k) {for (int i = x; i <= 3e6; i += lowbit(i)) {tr[i] += k;}
}
int query(int x) {int res = 0;for (int i = x; i; i -= lowbit(i)) {res += tr[i];}return res;
}
void solve() {int q;std::cin >> q;for (int i = 1; i <= q; i ++) {int n, k;std::cin >> n >> k;V[n].push_back({k, i});}for (int i = 1; i <= 3e6; i ++) {if (i != 1) add(minp[i], 1);for (auto [k, id] : V[i]) {ans[id] = query(3e6) - query(k - 1);}}for (int i = 1; i <= q; i ++) {std::cout << ans[i] << "\n";}
}
signed main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int t = 1;P_init(3e6);while(t --) {solve();}return 0;
}