hdu4325 Flowers

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

这题需要用到离散化,因为10^9建立线段树会超时,而给的数字总共只有2*n+m,所以可以先离散化,(这里注意因为最后询问的时候所查询的时间可能没有在前n对出现,如果只对n对数字离散化,后面询问的时候会出错),我的离散化是先构造一个结构体储存输入的2*n+m的数的数字num和编号id,然后对关键词num排序,去重后用map<int,int>匹配编号,匹配完后再对id排序复原。离散化的另一个方法是定义一个结构体记录数的id(编号),num(数的大小),先根据num排序,然后依次赋值为i,最后再按id排序。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 300006
int sum,pos[maxn];
struct node{
	int l,r,sum;
}b[4*maxn];

struct edge{
	int id,num;
}a[maxn];

bool cmp1(edge a,edge b){
	return a.num<b.num;
}
bool cmp2(edge a,edge b){
	return a.id<b.id;
}

void build(int l,int r,int i)
{
	int mid;
	b[i].l=l;b[i].r=r;b[i].sum=0;
	if(l==r)return;
	mid=(l+r)/2;
	build(l,mid,i*2);
	build(mid+1,r,i*2+1);
}

void update(int l,int r,int i)
{
	int mid;
	if(b[i].l==l && b[i].r==r){
		b[i].sum++;return;
	}
	mid=(b[i].l+b[i].r)/2;
	if(r<=mid)update(l,r,i*2);
	else if(l>mid)update(l,r,i*2+1);
	else {
		update(l,mid,i*2);
		update(mid+1,r,i*2+1);
	}
}

void question(int id,int i)
{
	int mid;
	if(b[i].l==b[i].r){
		sum=b[i].sum;return;
	}
	b[i*2].sum+=b[i].sum;
	b[i*2+1].sum+=b[i].sum;
	b[i].sum=0;
	mid=(b[i].l+b[i].r)/2;
	if(id<=mid)question(id,i*2);
	else question(id,i*2+1);
}

int main()
{
	int n,m,i,j,T,h,c,d,t;
	map<int,int>hash;
	scanf("%d",&T);
	for(h=1;h<=T;h++){
		printf("Case #%d:\n",h);
		scanf("%d%d",&n,&m);
		build(1,maxn,1);
		for(i=1;i<=n;i++){
			scanf("%d%d",&a[i].num,&a[i+n].num);
			a[i].id=i;a[i+n].id=i+n;
		}
		for(i=1;i<=m;i++){
			scanf("%d",&a[i+2*n].num);
			a[i+2*n].id=i+2*n;
		}
		sort(a+1,a+2*n+m+1,cmp1);
		hash[a[1].num]=1;t=1;
		for(i=2;i<=2*n+m;i++){
			if(a[i].num!=a[i-1].num){
				t++;hash[a[i].num]=t;
			}
		}
		sort(a+1,a+2*n+m+1,cmp2);
		for(i=1;i<=n;i++){
			c=hash[a[i].num];d=hash[a[i+n].num];
			//printf("%d %d\n",c,d);
			update(c,d,1);
		}
		
		for(i=1;i<=m;i++){
			c=hash[a[i+2*n].num];
			sum=0;
			question(c,1);
			printf("%d\n",sum);
		}
	}
	return 0;
}


你可能感兴趣的:(线段树,离散化)