# 洛谷P1081 开车旅行

## 洛谷P1081 开车旅行

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int MAX = 1e5 + 10;
int n, m;
ll x;
struct node {
int i, l, r;
ll h;
}city[MAX];
int s;
int p[MAX], near[MAX], cnear[MAX];
int f[MAX][21];
ll sta[MAX][21], stb[MAX][21];

bool cmp(node a, node b)
{
return a.h < b.h;
}

bool panduan(int i,int l,int r)
{
if (!l)return 0;
if (!r)return 1;
return (city[i].h - city[l].h) <= (city[r].h - city[i].h);
}

int pb(int j, int a, int b)
{
if (!a)return city[b].i;
if (!b)return city[a].i;
if ((city[j].h - city[a].h) <= (city[b].h - city[j].h))return city[a].i;
return city[b].i;
}

void make_st()
{
for (int j = 1; j <= 19; j++)
{
for (int i = 1; i <= n; i++)
{
f[i][j] = f[f[i][j - 1]][j - 1];
sta[i][j] = sta[i][j - 1] + sta[f[i][j - 1]][j - 1];
stb[i][j] = stb[i][j - 1] + stb[f[i][j - 1]][j - 1];
}
}
}

void getab(ll x, int p, int &a, int &b)
{
a = b = 0;
for (int j = 19; j >= 0; j--)
{
if (f[p][j] && (long long)(a + b + sta[p][j] + stb[p][j]) <= x)
{
a += sta[p][j];
b += stb[p][j];
p = f[p][j];
}
}
if (cnear[p] && a + b + sta[p][0] <= x)a += sta[p][0];
}

int main()
{
double minn = 1e9 + 10;
int ans = 0;
cin >> n;
for (int i = 1; i <= n; i++)cin >> city[i].h;
for (int i = 1; i <= n; i++)city[i].i = i;
sort(city + 1, city + 1 + n, cmp);
for (int i = 1; i <= n; i++)p[city[i].i] = i;
for (int i = 1; i <= n; i++) { city[i].l = i - 1; city[i].r = i + 1; }
city[1].l = city[n].r = 0;
for (int i = 1; i <= n; i++)
{
int j = p[i], l = city[j].l, r = city[j].r;
if (panduan(j, l, r)) { near[i] = city[l].i; cnear[i] = pb(j, city[l].l, r); }
else { near[i] = city[r].i; cnear[i] = pb(j, l, city[r].r); }
if (l)city[l].r = r;
if (r)city[r].l = l;
}

for (int i = 1; i <= n; i++)
{
f[i][0] = near[cnear[i]];
sta[i][0] = abs(city[p[i]].h - city[p[cnear[i]]].h);
stb[i][0] = abs(city[p[cnear[i]]].h - city[p[f[i][0]]].h);
}
make_st();

cin >> x >> m;
int a, b;
for (int i = 1; i <= n; i++)
{
getab(x, i, a, b);
if (b&&1.0*a / b < minn)
{
minn = 1.0*a / b;
ans = i;
}
}
cout << ans << endl;
for (int i = 1; i <= m; i++)
{
cin >> s >> x;
getab(x, s, a, b);
cout << a << ' ' << b << endl;
}

system("pause");
return 0;
}
03-29 279

04-10 25
07-15 408
10-30 732
08-10 220