您的位置:首页 > 其它

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

2016-09-07 21:28 525 查看


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

inputoutput
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<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
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<R) ret+=query(L,R,rson);
return ret;
}
int bit[maxn];
int ask[maxn];
struct arr{
int a,b,idx;
}p[maxn];
bool comp(const arr &e1,const arr &e2){
return (e1.b -e1.a )>(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]<x) l=mid+1;
else return mid;
}
}
int main(){
//freopen("D:\\in.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
int cnt=1;
memset(lazy,0,sizeof(lazy));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++){
scanf("%d%d",&p[i].a,&p[i].b);
bit[cnt++]=p[i].a ;
bit[cnt++]=p[i].b ;
p[i].idx= i;
}
sort(p+1,p+n+1,comp);
scanf("%d",&Q);
for(int j=0;j<Q;j++){
scanf("%d",&ask[j]);
bit[cnt++]=ask[j];
}
sort(bit+1,bit+cnt+1);
sz= unique(bit+1,bit+1+cnt)-(bit+1);
update(1,sz,-1,1,sz,1);
for(int i=1;i<=n;i++){
int newa=get(p[i].a);
int newb=get(p[i].b);
update(newa,newb,p[i].idx,1,sz,1);
}
for(int j=0;j<Q;j++){
int newask=get(ask[j]);
printf("%d\n",query(newask,newask,1,sz,1));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: