Immortal title
Offline and Enumeration will ask the right end, to maintain a position of each \ (I \) in all its positions after the \ (J \) from the minimum value of the interval is then taken min. Worst complexity of such an approach is apparently \ (O (n ^ 2) \) , we need some pruning.
We consider a location for a \ (i \) , after which the real is likely to update the minimum of what position. Assuming that the sequence \ (\ {a \} \ ) is an increasing sequence, \ (A_1> I, val_ A_1} {\ GEQ val_i \) , and wherein each time the right to take a certain point \ (a_j \) when \ (I \) minimum location update will be effective, it would be met: \ (\ FORALL J \ in [. 1, | a |), | val_i - val_ a_j {} | \ GEQ 2 | val_i - val_ + J. 1 A_ {{}} | \) , because if this condition is not satisfied then the \ (a_j \) and \ (a_ {j + 1} \) distance will be smaller at this time \ (I \ ) update is invalid.
Not difficult to find the above \ (a \) the length of the sequence will only have a maximum of \ (log 10 ^ 9 \) key, so we can use the tree line to find out what the position when the right point to the need to modify \ (i \ ) position, then move the right point to update and statistics answer. Complexity \ (O (nlog ^ 2n + qlogn) \)
#include<bits/stdc++.h>
using namespace std;
int read(){
int a = 0; char c = getchar(); bool f = 0;
while(!isdigit(c)){f = c == '-'; c = getchar();}
while(isdigit(c)){
a = a * 10 + c - 48; c = getchar();
}
return f ? -a : a;
}
const int _ = 3e5 + 7;
int cnt , N , M , arr[_] , lsh[_] , id[_] , L[_] , R[_] , ans[_]; vector < int > Q[_] , pos[_];
namespace segt{
int mn[_ << 2];
#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)
void clear(){memset(mn , 0x3f , sizeof(mn));}
void modify(int x , int l , int r , int tar , int val){
mn[x] = min(mn[x] , val); if(l == r) return;
mid >= tar ? modify(lch , l , mid , tar , val) : modify(rch , mid + 1 , r , tar , val);
}
int qry(int x , int l , int r , int L , int R){
if(l >= L && r <= R) return mn[x];
int mn = 1e9;
if(mid >= L) mn = qry(lch , l , mid , L , R);
if(mid < R) mn = min(mn , qry(rch , mid + 1 , r , L , R));
return mn;
}
}using namespace segt;
int main(){
N = read(); segt::clear(); for(int i = 1 ; i <= N ; ++i) arr[i] = lsh[i] = read();
M = read(); for(int i = 1 ; i <= M ; ++i){L[i] = read(); R[i] = read(); Q[R[i]].push_back(i);}
sort(lsh + 1 , lsh + N + 1); cnt = unique(lsh + 1 , lsh + N + 1) - lsh - 1;
for(int i = 1 ; i <= N ; ++i) id[i] = lower_bound(lsh + 1 , lsh + cnt + 1 , arr[i]) - lsh;
for(int i = N , cur , t ; i ; --i){
cur = cnt;
while((t = segt::qry(1 , 1 , cnt , id[i] , cur)) <= N){
pos[t].push_back(i); if(id[t] == id[i]) break;
cur = upper_bound(lsh + 1 , lsh + cnt + 1 , (arr[i] + arr[t]) / 2) - lsh - 1;
}
cur = 1;
while((t = segt::qry(1 , 1 , cnt , cur , id[i])) <= N){
pos[t].push_back(i); if(id[t] == id[i]) break;
cur = lower_bound(lsh + 1 , lsh + cnt + 1 , (arr[i] + arr[t] + 1) / 2) - lsh;
}
segt::modify(1 , 1 , cnt , id[i] , i);
}
segt::clear();
for(int i = 1 ; i <= N ; ++i){
for(auto t : pos[i]) segt::modify(1 , 1 , N , t , abs(arr[i] - arr[t]));
for(auto t : Q[i]) ans[t] = segt::qry(1 , 1 , N , L[t] , i);
}
for(int i = 1 ; i <= M ; ++i) printf("%d\n" , ans[i]);
return 0;
}