#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
using u128 = unsigned __int128;
using namespace std;
//板子板子板子板子板子板子
// 线段树节点结构体
struct Node {
i64 sum = 0; // 区间和
i64 max_val = LLONG_MIN; // 区间最大值
i64 min_val = LLONG_MAX; // 区间最小值
i64 lazy = 0; // 延迟标记
i64 left = 0; // 区间左端点
i64 right = 0; // 区间右端点
};
class SegmentTree {
private:
vector<Node> tree; // 线段树数组
vector<i64> data; // 原始数据
// 构建线段树
void build(i64 rt, i64 left, i64 right) {
tree[rt].left = left;
tree[rt].right = right;
tree[rt].lazy = 0;
if (left == right) {
tree[rt].sum = data[left];
tree[rt].max_val = data[left];
tree[rt].min_val = data[left];
return;
}
i64 mid = (left + right) / 2;
build(2 * rt, left, mid); // 递归构建左子树
build(2 * rt + 1, mid + 1, right); // 递归构建右子树
tree[rt].sum = tree[2 * rt].sum + tree[2 * rt + 1].sum; // 更新区间和
tree[rt].max_val = max(tree[2 * rt].max_val, tree[2 * rt + 1].max_val); // 更新区间最大值
tree[rt].min_val = min(tree[2 * rt].min_val, tree[2 * rt + 1].min_val); // 更新区间最小值
}
// 延迟标记下传
void pushDown(i64 rt) {
if (tree[rt].lazy != 0) {
i64 lson = 2 * rt;
i64 rson = 2 * rt + 1;
i64 mid = (tree[rt].left + tree[rt].right) / 2;
// 更新左子节点
tree[lson].sum += tree[rt].lazy * (mid - tree[rt].left + 1);
tree[lson].max_val += tree[rt].lazy;
tree[lson].min_val += tree[rt].lazy;
tree[lson].lazy += tree[rt].lazy;
// 更新右子节点
tree[rson].sum += tree[rt].lazy * (tree[rt].right - mid);
tree[rson].max_val += tree[rt].lazy;
tree[rson].min_val += tree[rt].lazy;
tree[rson].lazy += tree[rt].lazy;
tree[rt].lazy = 0; // 清空当前节点的延迟标记
}
}
public:
// 构造函数,初始化线段树
SegmentTree(const vector<i64>& input) : data(input) {
i64 n = data.size() - 1; // 数据从下标1开始
tree.resize(4 * n + 1); // 线段树大小为4倍数据大小
build(1, 1, n); // 从根节点开始构建
}
// 区间更新:将区间 [ul, ur] 内的每个数加上 k
void updateRange(i64 rt, i64 ul, i64 ur, i64 k) {
i64 left = tree[rt].left;
i64 right = tree[rt].right;
if (ur < left || ul > right) {
return; // 当前区间与更新区间无交集
}
if (ul <= left && ur >= right) {
// 当前区间完全包含在更新区间内
tree[rt].sum += k * (right - left + 1);
tree[rt].max_val += k;
tree[rt].min_val += k;
tree[rt].lazy += k;
return;
}
pushDown(rt); // 下传延迟标记
updateRange(2 * rt, ul, ur, k); // 更新左子树
updateRange(2 * rt + 1, ul, ur, k); // 更新右子树
tree[rt].sum = tree[2 * rt].sum + tree[2 * rt + 1].sum; // 更新当前节点
tree[rt].max_val = max(tree[2 * rt].max_val, tree[2 * rt + 1].max_val); // 更新区间最大值
tree[rt].min_val = min(tree[2 * rt].min_val, tree[2 * rt + 1].min_val); // 更新区间最小值
}
// 区间查询:查询区间 [ql, qr] 的和
i64 querySum(i64 rt, i64 ql, i64 qr) {
i64 left = tree[rt].left;
i64 right = tree[rt].right;
if (qr < left || ql > right) {
return 0; // 当前区间与查询区间无交集
}
if (ql <= left && qr >= right) {
return tree[rt].sum; // 当前区间完全包含在查询区间内
}
pushDown(rt); // 下传延迟标记
return querySum(2 * rt, ql, qr) + querySum(2 * rt + 1, ql, qr); // 返回左右子树的查询结果
}
// 区间查询:查询区间 [ql, qr] 的最大值
i64 queryMax(i64 rt, i64 ql, i64 qr) {
i64 left = tree[rt].left;
i64 right = tree[rt].right;
if (qr < left || ql > right) {
return LLONG_MIN; // 当前区间与查询区间无交集
}
if (ql <= left && qr >= right) {
return tree[rt].max_val; // 当前区间完全包含在查询区间内
}
pushDown(rt); // 下传延迟标记
return max(queryMax(2 * rt, ql, qr), queryMax(2 * rt + 1, ql, qr)); // 返回左右子树的最大值
}
// 区间查询:查询区间 [ql, qr] 的最小值
i64 queryMin(i64 rt, i64 ql, i64 qr) {
i64 left = tree[rt].left;
i64 right = tree[rt].right;
if (qr < left || ql > right) {
return LLONG_MAX; // 当前区间与查询区间无交集
}
if (ql <= left && qr >= right) {
return tree[rt].min_val; // 当前区间完全包含在查询区间内
}
pushDown(rt); // 下传延迟标记
return min(queryMin(2 * rt, ql, qr), queryMin(2 * rt + 1, ql, qr)); // 返回左右子树的最小值
}
};
struct arry{
i64 nums;
i64 xuhao;
};
bool com(arry x,arry y){
return x.nums<y.nums;
}
void solve() {
// 示例数据
i64 n;
cin>>n;
vector<i64> data (n+1,0); // 数据从下标1开始
for(int i = 1; i<= n ; i++){
cin>>data[i];
}
SegmentTree st(data);
vector <arry> nums(n+1);
for (int i = 1; i <=n; ++i)
{
nums[i].nums=data[i];
nums[i].xuhao=i;
}
sort(nums.begin()+1,nums.end(),com);
vector <i64 > minnums;
i64 l=nums[1].xuhao;
i64 r=nums[1].xuhao;
i64 i=1;
while(r!=n)
{
i64 tree_max_num=st.queryMax(1,l,r)*2;
i64 tree_min_num=st.queryMin(1,l,r)*2;
i64 whole_max_num=max(st.queryMax(1,1,l-1),st.queryMax(1,r+1,n));
i64 whole_min_num=min(st.queryMin(1,1,l-1),st.queryMin(1,r+1,n));
minnums.push_back(max(max(tree_max_num,whole_max_num),max(tree_min_num,whole_min_num))-min(min(tree_min_num,whole_min_num),min(tree_max_num,whole_max_num)));
l=min(l,nums[i+1].xuhao);
r=max(r,nums[i+1].xuhao);
i+=1;
}
minnums.push_back(2*(st.queryMax(1,1,n)-st.queryMin(1,1,n)));
sort(minnums.begin(),minnums.end());
cout<<minnums[0]<<endl;
// 操作1:区间更新,将区间 [2, 4] 内的每个数加上 2
//st.updateRange(1, 2, 4, 2);
// 操作2:区间查询,查询区间 [2, 4] 的和
//cout << "Sum of [2, 4]: " << st.querySum(1, 2, 4) << endl; // 输出:11
// 操作3:区间查询,查询区间 [2, 4] 的最大值
//cout << "Max of [2, 4]: " << st.queryMax(1, 2, 4) << endl; // 输出:6
// 操作4:区间查询,查询区间 [2, 4] 的最小值
//cout << "Min of [2, 4]: " << st.queryMin(1, 2, 4) << endl; // 输出:4
// 操作5:区间更新,将区间 [1, 5] 内的每个数加上 1
//st.updateRange(1, 1, 5, 1);
// 操作6:区间查询,查询区间 [1, 4] 的和
//cout << "Sum of [1, 4]: " << st.querySum(1, 1, 4) << endl; // 输出:20
// 操作7:区间查询,查询区间 [1, 4] 的最大值
//cout << "Max of [1, 4]: " << st.queryMax(1, 1, 4) << endl; // 输出:7
// 操作8:区间查询,查询区间 [1, 4] 的最小值
//cout << "Min of [1, 4]: " << st.queryMin(1, 1, 4) << endl; // 输出:3
return ;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin >> t;
while (t--) {
solve();
}
return 0;
}

