hdoj 4325 Flowers 线段树+离散化

随声附和 提交于 2020-01-05 03:05:23

hdoj 4325 Flowers

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4325

思路:

直接线段树,按照花的开放区间的大小建树,要注意虽然花的周期数据可能会达到1e9,这样的话线段树开四倍时不可能的。但是我们可以看到一共可能的数据时N行,那么每行两个数,再开4倍的区间。计算下来,在离散化的帮助下,我们只需要开8*N被的线段树即可。
另外询问的数据也需要放入离散化的范围,如果不这样做,有可能在询问时使用lower_bound函数会导致数据的改变,询问的原数据发生变化。
eg:1~3 7~10 询问6,结果应该时0,但因为lower_bound的原因询问时使用7,得到结果1。etc.

代码:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn = 1e5+5;
struct node {
    int l,r,sum,lazy;
    inline void update(int val) {
        lazy+=val;
        sum+=val;
    }
} tr[maxn*8];
int a[maxn],b[maxn],c[maxn<<1],d[maxn];
inline void push_down(int s) {
    int lazyval = tr[s].lazy;
    if(!lazyval) return;
    tr[s<<1].update(lazyval);
    tr[s<<1|1].update(lazyval);
    tr[s].lazy=0;
}
void build(int s, int l, int r) {
    tr[s].l=l;tr[s].r=r;
    tr[s].lazy=tr[s].sum=0;
    if(l==r) return;
    int mid = (l+r)>>1;
    build(s<<1,l,mid);
    build(s<<1|1,mid+1,r);
}
void update(int s, int l, int r) {
    if(tr[s].l==l&&tr[s].r==r) {
        tr[s].update(1);
        return;
    }
    push_down(s);
    int mid = (tr[s].l+tr[s].r)>>1;
    if(r<=mid) update(s<<1,l,r);
    else if(l>mid) update(s<<1|1,l,r);
    else {
        update(s<<1,l,mid);
        update(s<<1|1,mid+1,r);
    }
}
int query(int s, int l, int r) {
    if(tr[s].l==l&&tr[s].r==r) {
        return tr[s].sum;
    }
    push_down(s);
    int mid=(tr[s].l+tr[s].r)>>1;
    if(r<=mid) return query(s<<1,l,r);
    else return query(s<<1|1,l,r);
}
int main() {
    int t,n,m,tot;
    scanf("%d",&t);
    for(int j=1;j<=t;++j) {
        scanf("%d %d",&n,&m);
        tot=1;
        for(int i=1;i<=n;++i) {
            scanf("%d %d",&a[i],&b[i]);
            c[tot++]=a[i];c[tot++]=b[i];
        }
        for(int i=1;i<=m;++i) {
            scanf("%d",&d[i]);
            c[tot++]=d[i];
        }
        sort(c+1,c+tot);
        tot=unique(c+1,c+tot)-(c+1);
        build(1,1,tot);
        for(int i=1;i<=n;++i) {
            a[i]=lower_bound(c+1,c+tot,a[i])-c;
            b[i]=lower_bound(c+1,c+tot,b[i])-c;
            update(1,a[i],b[i]);
        }
        printf("Case #%d:\n",j);
        for(int i=1;i<=m;++i) {
            d[i]=lower_bound(c+1,c+tot,d[i])-c;
            printf("%d\n",query(1,d[i],d[i]));
        }
    }
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!