【hdu4325】【线段树】Flowers 动态建树

Flowers

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

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

2012 Multi-University Training Contest 3

Recommend

zhoujiaqi2010

线段树基本操作,因为长度是 109 所以这里要动态建树
好像如果用数组写线段树可以用离散化来做

然后操作很基本,区间修改,单点查询,查询的时候如果没有儿子节点说明那一片都是一样的,直接返回那一片就好了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define INF 2100000000
#define ll long long
#define clr(x)  memset(x,0,sizeof(x))
#define clrmax(x)  memset(x,127,sizeof(x))

using namespace std;

inline int read()
{
    char c;
    int ret=0;
    while(!(c>='0'&&c<='9'))
        c=getchar();
    while(c>='0'&&c<='9')
    {
        ret=(c-'0')+(ret<<1)+(ret<<3);
        c=getchar();
    }
    return ret;
}

#define M 100005

struct tree2
{
    tree2 *lson,*rson;
    int n,lazy;
}*root,dizhi[M*25];

int t,n,q;

void update(tree2 *tree)
{
    if(tree->lson==NULL)tree->lson=&dizhi[t++];
    if(tree->rson==NULL)tree->rson=&dizhi[t++];
    tree->lson->lazy+=tree->lazy;
    tree->rson->lazy+=tree->lazy;
    tree->lson->n+=tree->lazy;
    tree->rson->n+=tree->lazy;
    tree->lazy=0;
}

void change(tree2 *tree,int l,int r,int x,int y)
{
    if(l==r||(x<=l&&y>=r))
    {
        tree->n++;
        tree->lazy++;
        return ;
    }
    if(tree->lazy)update(tree);
    int mid=(l+r)>>1;
    if(x<=mid)
    {
        if(tree->lson==NULL)tree->lson=&dizhi[t++];
        change(tree->lson,l,mid,x,y);
    }
    if(y>mid)
    {
        if(tree->rson==NULL)tree->rson=&dizhi[t++];
        change(tree->rson,mid+1,r,x,y);
    }
}

int find(tree2 *tree,int l,int r,int x)
{
    if(l==r||(tree->lazy&&tree->lson==NULL&&tree->rson==NULL))
        return tree->n;
    int mid=(l+r)>>1;
    if(x<=mid)
        if(tree->lson==NULL)return tree->n;
        else 
        {
            if(tree->lazy)update(tree);
            return find(tree->lson,l,mid,x);
        }
    else if(tree->rson==NULL)return tree->n;
         else 
         {
            if(tree->lazy)update(tree);
            return find(tree->rson,mid+1,r,x);
         }
}

int main()
{
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    int T,ca=0;
    T=read();
    while(T--)
    {
        ca++;
        clr(dizhi);
        t=0;
        root=&dizhi[t++];
        n=read();q=read();
        for(int i=1;i<=n;i++)
        {
            int a=read(),b=read();
            change(root,1,1E9,a,b);
        }
        printf("Case #%d:\n",ca);
        for(int i=1;i<=q;i++)
        {
            int a=read();
            printf("%d\n",find(root,1,1E9,a));
        }
    }
    return 0;
}

大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值