• hdoj 4325 Flowers 线段树+离散化


    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:
    ",j);
            for(int i=1;i<=m;++i) {
                d[i]=lower_bound(c+1,c+tot,d[i])-c;
                printf("%d
    ",query(1,d[i],d[i]));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    python之函数名,闭包、迭代器
    python-函数进阶-动态传参,名称空间,作用域的问题
    python之初识函数
    python之文件处理
    重新执笔,已是大三!Jekyll自定义主题开发
    HDU -2674 N!Again(小技巧)
    HDU -2546饭卡(01背包+贪心)
    NYOJ 1091 超大01背包(折半枚举)
    HDU 5144 NPY and shot(三分法)
    printf用法之打印2进制,八进制,十进制,十六进制
  • 原文地址:https://www.cnblogs.com/lemonbiscuit/p/7899253.html
Copyright © 2020-2023  润新知