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;
}

 

posted @ 2013-04-23 23:03  Jack Ge  阅读(262)  评论(0编辑  收藏  举报