码迷,mamicode.com
首页 > 其他好文 > 详细

URAL1987. Nested Segments 线段树

时间:2015-03-14 21:45:19      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:线段树

1987. Nested Segments

Time limit: 1.0 second
Memory limit: 64 MB
You are given n segments on a straight line. For each pair of segments it is known that they either have no common points or all points of one segment belong to the second segment.
Then m queries follow. Each query represents a point on the line. For each query, your task is to find the segment of the minimum length, to which this point belongs.

Input

The first line contains an integer n that is the number of segments (1 ≤ n ≤ 105). i’th of the next n lines contains integers ai and bi that are the coordinates of endpoints of the i’th segment (1 ≤ ai < bi ≤ 109). The segments are ordered by non-decreasing ai, and when ai = aj they are ordered by decreasing length. All segments are distinct. The next line contains an integer m that is the number of queries (1 ≤ m ≤ 105). j’th of the next m lines contains an integer cj that is the coordinate of the point (1 ≤ cj ≤ 109). The queries are ordered by non-decreasing cj.

Output

For each query output the number of the corresponding segment on a single line. If the point does not belong to any segment, output “-1”. The segments are numbered from 1 to n in order they are given in the input.

Sample

input output
3
2 10
2 3
5 7
11
1
2
3
4
5
6
7
8
9
10
11
-1
2
2
1
3
3
3
1
1
1
-1




题意:
有n个段,编号1-n,每个段占据着a-b。 m个查询,查询c处所在的段中,长度最短的是几号段。如果没有段占据,输出-1。

首先把所有数字存在数组里,去离散化。然后把id按段的长度从长到短更新到树中。然后就查询固定的点在树中的ID的就行了。


#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define LL int
const int maxn = 811111; 
LL ID[maxn<<2];//记录该点属于哪一段
void PushUp(int rt) {
	if(ID[rt<<1] == ID[rt<<1|1])
		ID[rt]=ID[rt<<1];
	else 
	ID[rt] = -1;
}
void PushDown(int rt,int m) {    
	if(ID[rt]!=-1)
	{
		ID[rt<<1] = ID[rt];
		ID[rt<<1|1] = ID[rt];
	}
}
void build(int l,int r,int rt) { 
	if (l == r) {
		ID[rt]=-1;
		return ;
	}
	int m = (l + r) >> 1;
	build(lson);
	build(rson);
	PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt) {
	if (L <= l && r <= R) { 
		ID[rt] = c; 
		return ;
	}
	PushDown(rt , r - l + 1);
	int m = (l + r) >> 1;
	if (L <= m) update(L , R , c , lson);
	if (m < R) update(L , R , c , rson);
	PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt) {
	if (L <= l && r <= R) {
		return ID[rt];
	}
	PushDown(rt , r - l + 1);
	int m = (l + r) >> 1;
	LL ret = 0;
	if (L <= m) ret += query(L , R , lson);
	if (m < R) ret += query(L , R , rson);
	return ret;
}

  

map<int ,int >my;
struct bian
{
	int l,r,len;
	int id;
};
int num[800010];//用来记录输入的所有的数 用于去离散化
bian edge[100010];
int qus[100010];//记录询问
int cmp(bian a,bian b)
{
	return a.len<b.len;
}
int arr[800010];
int main()
{
	int i,a,b;
	int t,cas=1;
	int n;
	int ji;
	while(scanf("%d",&n)!=EOF)
	{ 
		my.clear();
		 
		ji=0;
		for(i=0;i<n;i++)
		{
			scanf("%d%d",&a,&b);
			edge[i].l=a;
			edge[i].r=b;
			edge[i].len=b-a;
			edge[i].id=i+1;
			num[ji++]=a;
			num[ji++]=b;
		}
		
		int m;
		scanf("%d",&m);
		for(i=0;i<m;i++)
		{
			scanf("%d",&qus[i]); 
			num[ji++]=qus[i];
		}

		sort(edge,edge+n,cmp);
		sort(num,num+ji);
		int ji2=1;
		for(i=1;i<ji;i++)
		{
			if(num[i]!=num[i-1])
				num[ji2++]=num[i];
		}

		ji=ji2;
		for(i=0;i<ji;i++)
			my[num[i]]=i+1; 

		build(1,ji,1); 
		for(i=n-1;i>=0;i--)//边长从大到小排序, 所以从后往前,边长短的会覆盖掉
		{
			int l=my[edge[i].l];
			int r=my[edge[i].r];
			update(l,r,edge[i].id,1,ji,1);
		}
		for(i=0;i<m;i++)
			printf("%d\n",query(my[qus[i]],my[qus[i]],1,ji,1)); 
	}
	return 0;
}







URAL1987. Nested Segments 线段树

标签:线段树

原文地址:http://blog.csdn.net/u013532224/article/details/44263445

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!