hdu 4417

(离线+树状数组 | 主席树)
题意:给定 n(n<105) 个数 ai(ai<109) m(m<105) 个询问,每次询问求 [l,r] 区间里小于等于 H(H<109) 的数字有多少个?

思路1:我们将数组 ai 从小到大排序,并且将询问依据 H 从小到大进行排序。然后每次枚举到一个询问时,就往树状数组中插入所有小于当前询问里 H 的数字 ai ,这样区间查询的结果就是符合要求的。总之,这个思路用离线处理的方法固化了”小于 H ”这个条件,使得题目变成了树状数组的区间修改查询问题。
(注意写while语句插入 ai 的时候 i 不要越界)

思路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;
}
发布了40 篇原创文章 · 获赞 44 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Site1997/article/details/78815171