Codeforces Round #238 (Div. 1)D. Hill Climbing

D. Hill Climbing
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

This problem has nothing to do with Little Chris. It is about hill climbers instead (and Chris definitely isn't one).

There are n hills arranged on a line, each in the form of a vertical line segment with one endpoint on the ground. The hills are numbered with numbers from 1 to n from left to right. The i-th hill stands at position xi with its top at height yi. For every two hills a and b, if the top of hill a can be seen from the top of hill b, their tops are connected by a rope. Formally, the tops of two hills are connected if the segment connecting their top points does not intersect or touch any of the other hill segments. Using these ropes, the hill climbers can move from hill to hill.

There are m teams of climbers, each composed of exactly two members. The first and the second climbers of the i-th team are located at the top of the ai-th and bi-th hills, respectively. They want to meet together at the top of some hill. Now, each of two climbers move according to the following process:

  1. if a climber is at the top of the hill where the other climber is already located or will come eventually, the former climber stays at this hill;
  2. otherwise, the climber picks a hill to the right of his current hill that is reachable by a rope and is the rightmost possible, climbs this hill and continues the process (the climber can also climb a hill whose top is lower than the top of his current hill).

For each team of climbers, determine the number of the meeting hill for this pair!

Input

The first line of input contains a single integer n (1 ≤ n ≤ 105), the number of hills. The next n lines describe the hills. The i-th of them contains two space-separated integers xiyi (1 ≤ xi ≤ 1071 ≤ yi ≤ 1011), the position and the height of the i-th hill. The hills are given in the ascending order of xi, i.e., xi < xj for i < j.

The next line of input contains a single integer m (1 ≤ m ≤ 105), the number of teams. The next m lines describe the teams. The i-th of them contains two space-separated integers aibi (1 ≤ ai, bi ≤ n), the numbers of the hills where the climbers of the i-th team are located. It is possible that ai = bi.

Output

In a single line output m space-separated integers, where the i-th integer is the number of the meeting hill for the members of the i-th team.

Sample test(s)
input
6
1 4
2 1
3 2
4 3
6 4
7 4
3
3 1
5 6
2 3
output
5 6 3 
把凸包上的问题转化为LCA
每个点的父亲为以他为起点凸包上的下一个点

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 120000
using namespace std;
#define ll long long
#define dd double
ll xx[maxn],yy[maxn];
int qu[maxn],he;
int n,m;
int f[maxn][23],dep[maxn];
int ask(int x,int y){
if(dep[x]<dep[y])swap(x,y);
if(dep[x]!=dep[y]){
for(int j=21;j>=1;j--)if(f[x][j]&&dep[f[x][j]]>=dep[y])x=f[x][j];
}
if(x==y)return x;
for(int j=21;j>=1;j--)if(f[x][j]&&f[x][j]!=f[y][j]){
x=f[x][j],y=f[y][j];
}
return f[x][1];
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld%lld",&xx[i],&yy[i]);
qu[he=1]=n;
dep[n]=1;
for(int i=n-1;i>=1;i--){
while(he>1&&(yy[qu[he]]-yy[i])*(xx[qu[he-1]]-xx[qu[he]])<(yy[qu[he-1]]-yy[qu[he]])*(xx[qu[he]]-xx[i]))he--;
f[i][1]=qu[he];
qu[++he]=i;
dep[i]=dep[f[i][1]]+1;
for(int j=1;f[i][j];j++)f[i][j+1]=f[f[i][j]][j];
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
printf("%d ",ask(a,b));
}

}

posted @ 2014-03-31 16:36  wangyucheng  阅读(336)  评论(0编辑  收藏  举报