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 S i and T i (1 <= S i <= T i <= 10^9), means i-th flower will be blooming at time [S i, T i].
In the next M lines, each line contains an integer T i, 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;

}

 

你可能感兴趣的:(HDU)