HDU

来源:互联网 发布:淘宝购物后怎么评价 编辑:程序博客网 时间:2024/06/06 05:55

题意:

给你一个长度为n的数组,然后m次查询,每次询问问你l到r区间有多少个数是小于等于H的。

思路:

主席树维护数据,用区间右树小于等于H的数的数量减去区间左树小于等于H的数的数量即可。

代码:

#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>using namespace std;#define ls l,mid#define rs mid+1,r#define mi (l+r)/2const int MAXN=1e5+7;vector <int> a;typedef struct Node{    int val;    int son[2];}Node;Node tree[MAXN*20];int b[MAXN];int cnt,pos,rtid[MAXN],ans,enn;int new_node(){    int rt=++cnt;    tree[rt].val=0;    tree[rt].son[0]=tree[rt].son[1]=0;    return rt;}int build(int l,int r){    int rt=new_node();    if(l==r){        return rt;    }    int mid=mi;    tree[rt].son[0]=build(ls);    tree[rt].son[1]=build(rs);    return rt;}void update(int l,int r,int rt,int lart){    tree[rt].val=tree[lart].val;    tree[rt].val++;    if(l==r) return ;    int mid=mi;    if(pos>mid){        tree[rt].son[0]=tree[lart].son[0];        tree[rt].son[1]=new_node();        update(mid+1,r,tree[rt].son[1],tree[lart].son[1]);    }else{        tree[rt].son[1]=tree[lart].son[1];        tree[rt].son[0]=new_node();        update(l,mid,tree[rt].son[0],tree[lart].son[0]);    }}int query(int l,int r,int rt){    if(l>enn) return 0;    if(r<=enn){        return tree[rt].val;    }    int mid=mi;    return query(ls,tree[rt].son[0])+query(rs,tree[rt].son[1]);}void ini(){    a.clear();cnt=0;}int main(){    int n,m,st,en,k,T;    vector <int>::iterator it;    scanf("%d",&T);    for(int Case=1;Case<=T;Case++){        scanf("%d%d",&n,&m);        ini();        for(int i=1;i<=n;i++) scanf("%d",&b[i]),a.push_back(b[i]);        sort(a.begin(),a.end());a.erase(unique(a.begin(),a.end()),a.end());        int len=a.size();        rtid[0]=build(1,len);        for(int i=1;i<=n;i++){            pos=lower_bound(a.begin(),a.end(),b[i])-a.begin()+1;            rtid[i]=++cnt;            update(1,len,rtid[i],rtid[i-1]);        }        printf("Case %d:\n",Case);        for(int i=1;i<=m;i++){            scanf("%d%d%d",&st,&en,&k);            it=upper_bound(a.begin(),a.end(),k);            if(it==a.end()){                enn=len;            }else{                enn=it-a.begin();            }            printf("%d\n",query(1,len,rtid[en+1])-query(1,len,rtid[st]));        }    }}