zoukankan      html  css  js  c++  java
  • HDU 4235 Flowers (线段树)

    Flowers

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1733    Accepted Submission(s): 858


    Problem Description
    As is known to all, the blooming time and duration varies between different kinds of flowers. Now there is a garden planted full of flowers. The gardener wants to know how many flowers will bloom in the garden in a specific time. But there are too many flowers in the garden, so he wants you to help him.
     
    Input
    The first line contains a single integer t (1 <= t <= 10), the number of test cases.
    For each case, the first line contains two integer N and M, where N (1 <= N <= 10^5) is the number of flowers, and M (1 <= M <= 10^5) is the query times. 
    In the next N lines, each line contains two integer Si and Ti (1 <= Si <= Ti <= 10^9), means i-th flower will be blooming at time [Si, Ti].
    In the next M lines, each line contains an integer Ti, means the time of i-th query.
     
    Output
    For each case, output the case number as shown and then print M lines. Each line contains an integer, meaning the number of blooming flowers.
    Sample outputs are available for more details.
     
    Sample Input
    2 1 1 5 10 4 2 3 1 4 4 8 1 4 6
     
    Sample Output
    Case #1: 0 Case #2: 1 2 1
     
    Author
    BJTU
     
    Source
     
    Recommend
    zhoujiaqi2010
     

     题意:给出N种花的开花时间,求出某一个时间点,得出开花数目

    思路:线段树+离散化,比赛时把代码写搓了半天弄不对, 主要是离散化离散的不好(PS:这也是我这个篇报告的原因) 原来我只是对所给的开花时间离散而已,并未对查询的时间也加到一块离散,弄得updata 和 query 操作过于麻烦 只要把要查询的时间也一块离散就方便多了 而且不易错。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    #define L(rt) (rt<<1)
    #define R(rt) (rt<<1|1)
    
    const int N=100010;
    
    struct node{
        int l,r,sum;    //sum 记录该区间被覆盖的次数
        int rl,rr;      //rl,rr是原来的区间长度
    }tree[N*3]; 
    
    struct data{
        int u,v;
    }seg[N];
    
    int tim[N<<1],Q[N];
    
    void build(int l,int r,int rt){
        tree[rt].l=l;
        tree[rt].r=r;
        tree[rt].rl=tim[tree[rt].l];
        tree[rt].rr=tim[tree[rt].r];
        tree[rt].sum=0;
        if(l==r)
            return ;
        int mid=(l+r)>>1;
        build(l,mid,L(rt));
        build(mid+1,r,R(rt));
    }
    
    void PushDown(int rt){   //这是延迟操作
        tree[L(rt)].sum+=tree[rt].sum;
        tree[R(rt)].sum+=tree[rt].sum;
        tree[rt].sum=0;
    }
    
    void update(int l,int r,int rt){
        if(l==tree[rt].rl && r==tree[rt].rr){
            tree[rt].sum+=1;
            return ;
        }
        if(tree[rt].sum!=0 && tree[rt].l!=tree[rt].r)
            PushDown(rt);
        int mid=(tree[rt].l+tree[rt].r)>>1;
        if(r<=tim[mid])
            update(l,r,L(rt));
        else if(l>=tim[mid+1])
            update(l,r,R(rt));
        else{
            update(l,tim[mid],L(rt));
            update(tim[mid+1],r,R(rt));
        }
    }
    
    int query(int num,int rt){
        if(tree[rt].sum!=0 && tree[rt].l!=tree[rt].r)
            PushDown(rt);
        if(tree[rt].l==tree[rt].r)
            return tree[rt].sum;
        int mid=tree[L(rt)].rr;
        if(num<=mid)
            return query(num,L(rt));
        else
            return query(num,R(rt));
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int t,n,m;
        int cases=0;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            tim[0]=-1;  //把tim初始为-1只是为了后面排序方便一些而已,也可不初始
            int cnt=1,u,v;
            for(int i=0;i<n;i++){
                scanf("%d%d",&u,&v);
                seg[i].u=u;
                seg[i].v=v;
                tim[cnt++]=u;
                tim[cnt++]=v;
            }
            int p;
            for(int i=0;i<m;i++){
                scanf("%d",&p);
                Q[i]=p;
                tim[cnt++]=p;
            }
            sort(tim,tim+cnt);              //离散化
            int len=unique(tim,tim+cnt)-(tim+1);
            build(1,len,1);
            for(int i=0;i<n;i++)
                update(seg[i].u,seg[i].v,1);
            printf("Case #%d:\n",++cases);
            for(int i=0;i<m;i++){
                int ans=query(Q[i],1);
                printf("%d\n",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    JavaEE编程实验 实验1 Java常用工具类编程(未完成)
    设计模式(一)Chain Of Responsibility责任链模式
    JavaSE习题 第八章 线程
    JavaSE习题 第七章 常用实用类
    JavaSE习题 第六章 字符串和正则表达式
    JavaSE 字符串和正则表达式
    HDFS的Shell操作
    HDFS概述
    Hadoop完全分布式模式
    免密登陆
  • 原文地址:https://www.cnblogs.com/jackge/p/3039197.html
Copyright © 2011-2022 走看看