(离线+树状数组 | 主席树)
题意:给定
思路1:我们将数组
(注意写while语句插入
思路2:主席树,待更
代码1:
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int a[maxn], ans[maxn], tree[maxn];
struct Num {
int num, pos;
Num(){}
Num(int a, int b):num(a),pos(b){}
bool operator < (const Num &A) const {
return num < A.num;
}
}mynum[maxn];
struct Query {
int id, l, r, mx;
Query(){}
Query(int a, int b, int c, int d):id(a),l(b),r(c),mx(d){}
bool operator < (const Query &A)const {
return mx < A.mx;
}
}qu[maxn];
int lowbit(int x) {
return x&(-x);
}
void update(int pos, int num) {
for(int i=pos; i<maxn; i+=lowbit(i))
tree[i] += num;
}
int get_sum(int pos) {
int ret = 0;
for(int i=pos; i>0; i-=lowbit(i))
ret += tree[i];
return ret;
}
int main() {
int T, n, m, cas = 0;
scanf("%d",&T);
while(T --) {
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
mynum[i] = Num(a[i], i);
}
sort(mynum+1, mynum+n+1);
for(int i=1; i<=m; i++) {
int l, r, mx;
scanf("%d%d%d",&l,&r,&mx);
qu[i] = Query(i, l+1, r+1, mx);
}
sort(qu+1, qu+m+1);
memset(tree, 0, sizeof(tree));
int cur = 1;
for(int i=1; i<=m; i++) {
while(cur <= n && mynum[cur].num <= qu[i].mx) {
update(mynum[cur].pos, 1);
cur ++;
}
int tot = get_sum(qu[i].r) - get_sum(qu[i].l-1);
//printf("get : %d %d\n",get_sum(qu[i].r),get_sum(qu[i].l-1));
ans[qu[i].id] = tot;
}
printf("Case %d:\n",++cas);
for(int i=1; i<=m; i++)
printf("%d\n",ans[i]);
}
return 0;
}