zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    学习web前端怎样入门?初学者赶紧看过来!
    web前端教程:CSS 布局十八般武艺都在这里了
    [zhuan]arm中的汇编指令
    adb命令
    [zhuan]使用uiautomator做UI测试
    [zhuan]java发送http的get、post请求
    Android 关于“NetworkOnMainThreadException”出错提示的原因及解决办法
    android getpost代码
    [转]Android 如何根据网络地址获取网络图片方法
    Android Json解析与总结
  • 原文地址:https://www.cnblogs.com/tiberius/p/9409784.html
Copyright © 2011-2022 走看看