# Solution

$a_r$将点分为两种：权值大于它的和小于它的。

$a_z < \frac{a_x + a_r}{2}$

# Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

const int N = 100000;
const int INF = 0x7f7f7f7f;

int n, a[N + 50], root[N + 50], tot, cwq, b[N + 50], q, pos;

{
int l, r, id, ans;
} ask[N * 3 + 50];

struct Bit
{
int minn[N + 50];
void Pre()
{
memset(minn, 0x7f, sizeof(minn));
return;
}
int Lowbit(int x)
{
return x & -x;
}
void Update(int pos, int v)
{
for (int i = pos; i <= n; i += Lowbit(i))
minn[i] = min(minn[i], v);
return;
}
int Query(int pos)
{
int minnn = INF;
for (int i = pos; i; i -= Lowbit(i)) minnn = min(minnn, minn[i]);
return minnn;
}
} bit;

struct SegmentTree
{
int s[(N << 2) + 50];
void Update(int k, int l, int r, int pos, int zhi)
{
if (l == r)
{
s[k] = zhi;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) Update(k << 1, l, mid, pos, zhi);
else Update(k << 1 | 1, mid + 1, r, pos, zhi);
s[k] = max(s[k << 1], s[k << 1 | 1]);
return;
}
int Query(int k, int l, int r, int x, int y)
{
if (x > y) return 0;
if (x <= l && r <= y) return s[k];
int mid = (l + r) >> 1;
if (y <= mid) return Query(k << 1, l, mid, x, y);
else if (x > mid) return Query(k << 1 | 1, mid + 1, r, x, y);
else return max(Query(k << 1, l, mid, x, y), Query(k << 1 | 1, mid + 1, r, x, y));
}
} tr;

{
x = 0; int p = 0; char st = getchar();
while (st < '0' || st > '9') p = (st == '-'), st = getchar();
while (st >= '0' && st <= '9') x = (x << 1) + (x << 3) + st - '0', st = getchar();
x = p ? -x : x;
return;
}

void Print(int x)
{
if (x > 9) Print(x / 10);
putchar(x % 10 + '0');
return;
}

{
return a.r < b.r;
}

{
return a.id < b.id;
}

int Abs(int x)
{
return x < 0 ? -x : x;
}

int Find(int x)
{
int l = 0, r = cwq;
while (l < r)
{
int mid = (l + r + 1) >> 1;
if (b[mid] <= x) l = mid;
else r = mid - 1;
}
return l;
}

int main()
{
for (int i = 1; i <= n; i++) Read(a[i]), b[++cwq] = a[i];
sort(b + 1, b + cwq + 1);
cwq = unique(b + 1, b + cwq + 1) - b - 1;
for (int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + cwq + 1, a[i]) - b;
pos = 1;
bit.Pre();
for (int i = 1; i <= n; i++)
{
if (i != 1)
{
int sj = cwq, xj = a[i], tmp;
tmp = tr.Query(1, 1, cwq, xj, sj);
while (tmp)
{
bit.Update(n - tmp + 1, Abs(b[a[tmp]] - b[a[i]]));
sj = Find((b[a[tmp]] + b[a[i]]) / 2);
if (!sj) break;
if (sj >= a[tmp]) sj = a[tmp] - 1;
tmp = tr.Query(1, 1, cwq, xj, sj);
}
sj = a[i], xj = 1;
tmp = tr.Query(1, 1, cwq, xj, sj);
while (tmp)
{
bit.Update(n - tmp + 1, Abs(b[a[tmp]] - b[a[i]]));
xj = Find((b[a[tmp]] + b[a[i]]) / 2);
if (!xj) break;
if (xj <= a[tmp]) xj = a[tmp] + 1;
tmp = tr.Query(1, 1, cwq, xj, sj);
}