原题链接
- 题意:静态区间询问比 (k) 大的数、小的数。
- 题解:主席树,但是问题是离散化的时候要注意,那个 (k) 也得加入离散化。
- 代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
using namespace std;
const int N = 2e5 * 80;
int a[N], b[N], rt[N], nn;
struct q{
int l, r, k;
}Q[N];
struct President_Tree {
struct node {
int l, r, data;
}tr[N];
int idx;
inline void create(int &p, int q, int l, int r, int num) {
p = ++idx;
tr[p] = tr[q];
tr[p].data++;
if (l == r)return;
int mid = l + r >> 1;
if (num <= mid) create(tr[p].l, tr[q].l, l, mid, num);
else create(tr[p].r, tr[q].r, mid + 1, r, num);
}
inline int ask(int p, int q, int l, int r, int k) {
int mid = l + r >> 1;
if (l == r)return tr[p].data - tr[q].data;//这个一开始没想明白,直接返回的 tr[p].data;
if (mid >= k) {//等于号要想一下为啥
return ask(tr[p].l, tr[q].l, l, mid, k);
} else {
return ask(tr[p].r, tr[q].r, mid + 1, r, k) + tr[tr[p].l].data - tr[tr[q].l].data;
}
}
}T;
int cas = 0;
signed main() {
int t;
scanf("%d", &t);
while (t--) {
T.idx = 0;
int n, m;scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]),b[i] = a[i];
printf("Case %d:
", ++cas);
for (int i = 1; i <= m; i ++) {
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
l++,r++;
Q[i] = {l, r, k};
b[n+ i] = k;
}
sort(b + 1, b + 1 + n + m);
nn = unique(b + 1, b + 1 + m+n) - b - 1;
for (int i = 1; i <= n; i ++) a[i] = lower_bound(b + 1, b + 1 + nn, a[i])-b, T.create(rt[i], rt[i-1], 1, nn, a[i]);
for (int i = 1; i <= m; i ++) {
int k = Q[i].k, r = Q[i].r, l = Q[i].l;
k = lower_bound(b + 1, b + 1 + nn, k) - b;
printf("%d
", T.ask(rt[r], rt[l-1], 1, nn, k));
}
}
}