题意:给你一个N大小的数列a[0].....a[n-1],输入L,R,H 求[L,R]区间内满足a[i]<=h的数的个数
这里我用了主席树来写
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100005;
const int M = N * 40;
int n,m,q,tot;
int a[N],t[N];
int T[N],ls[M],rs[M],c[M];
void Init_hash(){
sort(t+1,t+n+1);
m = unique(t+1,t+1+n)-t-1;
}
int hasha(int x){
return lower_bound(t+1,t+1+m,x)-t;
}
void build(int l, int r, int &rt){
rt = tot ++;
c[rt] = 0;
if(l != r){
int mid = (l+r)>>1;
build(l, mid, ls[rt] );
build(mid+1, r, rs[rt]);
}
}
int update(int root, int pos, int val){
int newroot = tot++, tmp = newroot;
c[newroot] = c[root] + val;
int l = 1, r = m;
while(l < r){
int mid = (l+r)>>1;
if(pos <= mid){
ls[newroot] = tot++;
rs[newroot] = rs[root];
newroot = ls[newroot];
root = ls[root];
r = mid;
}
else {
rs[newroot] = tot++;
ls[newroot] = ls[root];
newroot = rs[newroot];
root = rs[root];
l = mid+1;
}
c[newroot] = c[root] + val;
}
return tmp;
}
int query(int l_root, int r_root, int l, int r, int h){
if(t[r]<=h){
return c[r_root] - c[l_root];
}
int mid = (l+r)>>1, ans = 0;
if(t[l] <= h)ans+=query(ls[l_root],ls[r_root],l,mid,h);
if(t[mid+1] <= h)ans+=query(rs[l_root], rs[r_root], mid+1, r, h);
return ans;
}
int main(){
int l,r,h,ks,nn;
//freopen("in.txt","r",stdin);
scanf("%d",&nn);
for(int ks = 1; ks <= nn; ks++){
printf("Case %d:\n",ks);
scanf("%d%d",&n, &q);
tot = m = 0;
for(int i = 1; i <= n; i++ ){
scanf("%d", a+i);
t[i] = a[i];
}
Init_hash();
build(1,m,T[0]);
for(int i = 1; i <= n; i++){
T[i] = update(T[i-1], hasha(a[i]), 1);
}
for(int i = 0; i < q; i++){
scanf("%d%d%d", &l, &r, &h);
printf("%d\n",query(T[l],T[r+1],1,m,h));
}
}
return 0;
}