hdoj4325Flowers【线段树+离散化】



Flowers

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


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
 


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1000010;
int q[maxn];
int sum[maxn<<2];
int num[maxn<<1];
struct Node{
	int s,e;
}A[100010];
int ans;
bool cmp(int a,int b){
	return a<b;
}
int BS(int k,int n){
	int l=1,r=n;
	while(l<=r){
		int mid=(l+r)>>1;
		if(k==num[mid])return mid;
		else if(k<num[mid])r=mid-1;
		else l=mid+1;
	}
}
void update(int left,int right,int l,int r,int rt){
	if(left<=l&&r<=right){
		sum[rt]++;
		return ;
	}
	int mid=(l+r)>>1;
	if(left<=mid)update(left,right,lson);
	if(mid<right)update(left,right,rson);
}
void query(int pos,int l,int r,int rt){
	ans+=sum[rt];
	if(l==r)return;
	int mid=(l+r)>>1;
	if(pos<=mid)return query(pos,lson);
	else return query(pos,rson);
}
int main()
{
	int n,m,i,j,k,t,test=1;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		int cnt=1;
		for(i=0;i<n;++i){
			scanf("%d%d",&A[i].s,&A[i].e);
			num[cnt++]=A[i].s;
			num[cnt++]=A[i].e;
		}
		for(i=0;i<m;++i){
			scanf("%d",&q[i]);
			num[cnt++]=q[i];
		}
		sort(num,num+cnt,cmp);
		k=1;
		for(i=2;i<cnt;++i){
			if(num[i]!=num[i-1])num[++k]=num[i];
		}
		memset(sum,0,sizeof(sum));
		for(i=0;i<n;++i){
			int l=BS(A[i].s,k);
			int r=BS(A[i].e,k);
			update(l,r,1,k,1);
		}
		printf("Case #%d:\n",test++);
		for(i=0;i<m;++i){
			int pos=BS(q[i],k);
			ans=0;
			query(pos,1,k,1);
			printf("%d\n",ans);
		}
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值