换个角度思考
题意
每次查询区间里小于等于某个数的元素的个数,1e5范围
思路
离线操作,先对这组数排序,再对每个查询操作依据值排序,用树状数组更新及求和,每一次编号对应的值加一,从小到大计算不会出现错误。
错误点
- 貌似牛客int函数不写返回值会一直报段错误
占坑
其他dalao说是主席树模板题然而我并不会主席树
代码
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + 5;
int ans[maxn], sum[maxn];
struct node {
int v, id;
}a[maxn];
struct node2 {
int l, r, x, id;
}b[maxn];
int cmp(node x, node y) {
// if(x.v == y.v) return x.id<y.id;
return x.v < y.v;
}
int cmp2(node2 xx, node2 yy) {
return xx.x < yy.x;
}
int n, m;
int lowbit(int x) {
return x & (-x);
}
void update(int i, int k) { // pos i += k
while (i <= n) {
sum[i] += k;
// printf("pos %d += %d\n",i,k);
i += lowbit(i);
}
}
int getsum(int i) {
int res = 0;
while (i > 0) {
res += sum[i];
i -= lowbit(i);
}
return res;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i].v);
a[i].id = i;
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &b[i].l, &b[i].r, &b[i].x);
b[i].id = i;
}
sort(b + 1, b + m + 1, cmp2);
int i = 1, j = 1;
for (i = 1; i <= m; i++) {
while (b[i].x >= a[j].v && j <= n) {
update(a[j].id, 1);
j++;
}
ans[b[i].id] = getsum(b[i].r) - getsum(b[i].l - 1);
}
for (i = 1; i <= m; i++) {
printf("%d\n", ans[i]);
}
} 
京公网安备 11010502036488号