HDU 4417

Posted tiberius

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4417相关的知识,希望对你有一定的参考价值。

题意略。

思路:

仔细思考这个题目会发现,它其实是要你查询两次,第一是要规定l,r的范围,第二是要在范围内查询小于等于H的个数。所以有的人说要用主席树。

现在,如果我们能省去范围内对h的查询呢?也就是说,在查询范围时,我们就要保证这个范围内的所有hi都小于等于H的数字。

我们可以离线地来做。这样就只需要树状数组了,不再需要主席树了。

详见代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;

struct node{
    int idx,numb;
    node(int idx = 0,int numb = 0){
        this->idx = idx;
        this->numb = numb;
    }
};
struct query{
    int l,r,h,id;
    query(int l = 0,int r = 0,int h = 0,int id = 0){
        this->l = l,this->r = r,this->h = h;
        this->id = id;
    }
};

node store[maxn];
query depot[maxn];
int BIT[maxn],n,m,ans[maxn];

bool cmp1(const node& n1,const node& n2){
    return n1.numb < n2.numb;
}
bool cmp2(const query& q1,const query& q2){
    return q1.h < q2.h;
}
int lowbit(int k){
    return (k & -k);
}
void add(int pos,int val){
    while(pos <= n){
        BIT[pos] += val;
        pos += lowbit(pos);
    }
}
int sum(int pos){
    int ret = 0;
    while(pos > 0){
        ret += BIT[pos];
        pos -= lowbit(pos);
    }
    return ret;
}

int main(){
    int T,cas = 1;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        memset(BIT,0,sizeof(BIT));
        for(int i = 1;i <= n;++i){
            scanf("%d",&store[i].numb);
            store[i].idx = i;
        }
        sort(store + 1,store + 1 + n,cmp1);
        for(int i = 0;i < m;++i){
            scanf("%d%d%d",&depot[i].l,&depot[i].r,&depot[i].h);
            depot[i].id = i;
            depot[i].l += 1;
            depot[i].r += 1;
        }
        sort(depot,depot + m,cmp2);
        int last = 1;
        for(int i = 0;i < m;++i){
            int h = depot[i].h,l = depot[i].l;
            int r = depot[i].r,id = depot[i].id;
            for(;last <= n && store[last].numb <= h;++last)
                add(store[last].idx,1);
            int t = sum(r) - sum(l - 1);
            ans[id] = t;
        }
        printf("Case %d:
",cas++);
        for(int i = 0;i < m;++i)
            printf("%d
",ans[i]);
    }
    return 0;
}

 

以上是关于HDU 4417的主要内容,如果未能解决你的问题,请参考以下文章

代码源 Div1 - 108#464. 数数(主席树,区间比k小的数的个数)HDU4417

hdu 4417 Super Mario(主席树)

代码源 Div1 - 108#464. 数数(主席树,区间比k小的数的个数)HDU4417

[hdu 4417]树状数组+离散化+离线处理

HDU4417 Super Mario(主席树)

[HDU 4417]Super Mario