ural 1987. Nested Segments【离散化+贪心+线段树】

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 ≤ 10 5).  i’th of the next  n lines contains integers  a i and  b i that are the coordinates of endpoints of the  i’th segment (1 ≤  a i <  b i ≤ 10 9). The segments are ordered by non-decreasing  a i, and when  a i =  a j 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 ≤ 10 5).  j’th of the next  m lines contains an integer  c j that is the coordinate of the point (1 ≤  c j ≤ 10 9). The queries are ordered by non-decreasing  c j.

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
Problem Author: Mikhail Rubinchik, idea by Nikita Pervukhin

/*
    题意:给你n条线段和m次询问,每次询问要求输出包含该点的最短的线段的编号,
          如果不存在则输出-1
    类型:离散化+贪心+线段树
    分析:考虑到端点的范围在1e9以内,开不了那么大的数组,但是n的范围在1e5,所
          以我们要先进行离散化,然后用线段树把区间的值修改成-1,然后按照线段
          的长度从大到小排序,依次修改线段区间的值为线段的编号,这样就可以得
          到每个点对应的编号了
*/

#include
#include
#include
#include
#include
using namespace std;
#define int_inf ((1<<31)-1)
#define ll_inf ((1ll<<63)-1)

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;

const int maxn=110000*4*4;
using namespace std;
int n,Q;
int lazy[maxn<<2];
int sum[maxn<<2];
void PushUp(int rt){
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m){
	if(lazy[rt]){
		lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
		sum[rt<<1]=(m-(m>>1))*lazy[rt];
		sum[rt<<1|1]=((m>>1))*lazy[rt];
		lazy[rt]=0;
	}
}

void update(int L,int R,int c,int l,int r,int rt){
	if(L<=l && r<=R){
		lazy[rt]=c;
		sum[rt]=c*(r-l+1);
        return ;
	}
	PushDown(rt,r-l+1);
    int m=(l+r)>>1;
    if(L<=m) update(L,R,c,lson);
    if(R>m) update(L,R,c,rson);
    PushUp(rt);
}

int query(int L,int R,int l,int r,int rt){
	if(L<=l &&r<=R){
		return sum[rt];
	}
	PushDown(rt,r-l+1);
	int m=(r+l)>>1;
	int ret=0;
	if(L<=m) ret+=query(L,R,lson);
	if(m(e2.b -e2.a );
}
int sz;
int get(int x){
    int l=1,r=sz;
    while(r>=l){
        int mid=(l+r)>>1;
        if(bit[mid]>x) r=mid-1;
        else if(bit[mid]




你可能感兴趣的:(->,数据结构,<-,线段树&树状数组,离散化,贪心,URAL,->,技巧,<-)