对于每个点要找离它次近和最近的点,我们可以先把海拔高度排序,对于点i , 离他次近和最近的点一定在i-1,i-2,i+1,i+2这四个位置中,先找最近再找次近=、=
因为一直往右走,所以按排序前每个点的位置从左往右找,找完一个点删除,这样可以保证次近点和最近点都在该点的右边,同时可以保证信息的连续性。
sta[i][j]表示a在i这个点开车,过2^j轮后,a走的路程;stb同理
f[i][j]表示车在i这个点,过2^j轮(一轮为a先开一次车,b再开一次车)后,所到达的点;
我们可以用倍增处理出来;
然后可以通过sta[i][j],stb[i][j],f[i][j]求出出a到某点走的路程,和b某点走的路程
然后对于询问一,枚举每个点,找比值最小。
对于询问二,直接输出所求的距离就好
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct node
{
int v,num,l,r;
};
node q[100005];
int la, lb, n, m, ans, f[100005][21],p[100005],zj[100005],cj[100005];
long long sta[100005][21],stb[100005][21];
double mi = 1e30;
bool cmp(node const a,node const b)
{
return a.v < b.v;
}
bool zuo(int x)
{
if(q[x].r == 0) return 1;
if(q[x].l == 0) return 0;
return (q[x].v - q[q[x].l].v <= q[q[x].r].v - q[x].v)? 1 : 0;
}
int pd(int j,int x,int y)
{
if(x == 0) return q[y].num;
if(y == 0) return q[x].num;
if(q[j].v - q[y].v <=q[x].v - q[j].v) return q[y].num;
return q[x].num;
}
void init()
{
for(int i = 1; i <= 19; i++)
for(int j = 1; j <= n; j++)
{
f[j][i] = f[f[j][i-1]][i-1];
sta[j][i] = sta[j][i-1] + sta[f[j][i-1]][i-1];
stb[j][i] = stb[j][i-1] + stb[f[j][i-1]][i-1];
}
}
void getjl(int qd,int jl)
{
long long lc = 0;
for(int i = 19 ; i >= 0; i--)
{
if(f[qd][i] &&(long long)( sta[qd][i] + stb[qd][i] + lc) <= jl)
{
la += sta[qd][i];
lb += stb[qd][i];
lc = lc + sta[qd][i] + stb[qd][i];
qd = f[qd][i];
}
}
if(cj[qd] && lc + sta[qd][0] <= jl)
{
la += sta[qd][0];
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
scanf("%d",&q[i].v);
q[i].num = i;
}
sort(1+q,1+q+n,cmp);
for(int i = 1; i <= n;i++) p[q[i].num] = i;
for(int i = 1; i <= n; i++)
{
q[i].l = i - 1;
q[i].r = i + 1;
}
q[1].l = 0; q[n].r = 0;
for(int i = 1; i <= n; i++)
{
int j = p[i];
if(zuo(j)){zj[i] = q[q[j].l].num;cj[i] = pd(j,q[j].r,q[q[j].l].l);}
else {zj[i] = q[q[j].r].num;cj[i] = pd(j,q[q[j].r].r,q[j].l);}
if(q[j].l != 0) q[q[j].l].r = q[j].r;
if(q[j].r != 0) q[q[j].r].l = q[j].l;
}
for(int i = 1; i <= n; i++)
{
f[i][0] = zj[cj[i]];
sta[i][0] = abs(q[p[cj[i]]].v - q[p[i]].v);
stb[i][0] = abs(q[p[cj[i]]].v - q[p[f[i][0]]].v);
}
init();
int x0;
cin >> x0;
for(int i = 1; i <= n; i++)
{
la = 0;
lb = 0;
getjl(i,x0);
if(lb != 0 && (1.0* la/lb ) < mi)
{
mi = (1.0* la/lb );
ans = i;
}
}
cout << ans << endl;
cin >> m;
for(int i = 1 ;i <= m; i++)
{
la = 0;
lb = 0;
int qd,lc;
scanf("%d%d", &qd, &lc);
getjl(qd,lc);
cout << la << " " << lb << endl;
}
return 0;
}