Codeforces 765F Souvenirs

 

time limit per test 3 seconds
memory limit per test 512 megabytes
input standard input
output standard output

Artsem is on vacation and wants to buy souvenirs for his two teammates. There are n souvenir shops along the street. In i-th shop Artsem can buy one souvenir for ai dollars, and he cannot buy more than one souvenir in one shop. He doesn't want to introduce envy in his team, so he wants to buy two souvenirs with least possible difference in price.

Artsem has visited the shopping street m times. For some strange reason on the i-th day only shops with numbers from li to ri were operating (weird? yes it is, but have you ever tried to come up with a reasonable legend for a range query problem?). For each visit, Artsem wants to know the minimum possible difference in prices of two different souvenirs he can buy in the opened shops.

In other words, for each Artsem's visit you should find the minimum possible value of |as - at| where li ≤ s, t ≤ ris ≠ t.

Input

The first line contains an integer n (2 ≤ n ≤ 105).

The second line contains n space-separated integers a1, ..., an (0 ≤ ai ≤ 109).

The third line contains the number of queries m (1 ≤ m ≤ 3·105).

Next m lines describe the queries. i-th of these lines contains two space-separated integers li and ri denoting the range of shops working on i-th day (1 ≤ li < ri ≤ n).

Output

Print the answer to each query in a separate line.

Example
input
8
3 1 4 1 5 9 2 6
4
1 8
1 3
4 8
5 7
output
0
1
1
3

 

樹套樹 線段樹+set 腦洞題

將詢問按右端點從小到大排序。從左向右掃描,每次用當前點x更新從1到x位置的答案,然後回答所有右端點在x的詢問。

我們可以用線段樹更新每個位置答案的時候,這樣複雜度顯然比暴力更……劣了(可能需要遍歷每個位置)。

不過我們可以給線段樹加一些剪枝。當用a[x]更新區間[L,R]的時候,設當前最優答案是nowans 如果[L,R]區間內沒有在a[x]-nowans ~ a[x]+nowans範圍內的數,就不往深層更新了。

如何查找線段樹區間內有哪些數?結點上掛個平(s)衡(e)樹(t)即可。

↑爲了讓這個剪枝正確,更新的時候必須先更新線段樹右區間再更新左區間。

 

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<cstring>
 7 #include<set>
 8 using namespace std;
 9 const int INF=1e9;
10 const int mxn=400010;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 struct node{
18     int f;
19     set<int>st;
20 }t[mxn<<2];
21 int a[mxn];
22 set<int>::iterator it,it2;
23 struct query{
24     int L,R;
25     int id;
26     bool operator < (const query &b)const{
27         return (R==b.R && L<b.L) || R<b.R;
28     }
29 }q[mxn];
30 int ans[mxn];
31 int n,Q;
32 #define ls rt<<1
33 #define rs rt<<1|1
34 void Build(int l,int r,int rt){
35     t[rt].f=INF;
36     for(int i=l;i<=r;i++)t[rt].st.insert(a[i]);
37     if(l==r)return;
38     int mid=(l+r)>>1;
39     Build(l,mid,ls);Build(mid+1,r,rs);
40     it=t[rt].st.begin();
41     it2=it;it2++;
42     for(;it2!=t[rt].st.end();it++,it2++){
43         t[rt].f=min(t[rt].f,abs(*it2-*(it)));
44     }
45     return;
46 }
47 int query(int L,int R,int l,int r,int rt){
48 //    printf("L:%d R:%d l:%d r:%d rt:%d f:%d\n",L,R,l,r,rt,t[rt].f);
49     if(L<=l && r<=R)return t[rt].f;
50     int mid=(l+r)>>1;int res=INF;
51     if(L<=mid)res=min(res,query(L,R,l,mid,ls));
52     if(R>mid)res=min(res,query(L,R,mid+1,r,rs));
53     return res;
54 }
55 int nowans;
56 void update(int pos,int v,int l,int r,int rt){
57     if(l==r){
58         nowans=min(nowans,abs(a[l]-v));
59         t[rt].f=min(t[rt].f,nowans);
60     }
61     it=t[rt].st.lower_bound(v);
62     if(it!=t[rt].st.begin()){it2=it;it2--;}
63     if((it==t[rt].st.begin() || *(it2)<=v-nowans)&&(it==t[rt].st.end() || *(it)>=v+nowans)){
64         nowans=min(nowans,query(l,r,1,n,1));
65         return;
66     }
67     int mid=(l+r)>>1;
68     if(pos>mid)
69         update(pos,v,mid+1,r,rs);
70     update(pos,v,l,mid,ls);
71     t[rt].f=min(t[ls].f,t[rs].f);
72     return;
73 }
74 void solve(){
75     int i,j;
76     int hd=1;
77     for(i=1;i<=Q;i++){
78         while(hd<q[i].R){
79             nowans=INF;    update(hd,a[hd+1],1,n,1);    hd++;
80         }
81         ans[q[i].id]=query(q[i].L,q[i].R,1,n,1);
82     }
83     for(i=1;i<=Q;i++)printf("%d\n",ans[i]);
84     return;
85 }
86 int main(){
87     int i,j;
88     n=read();
89     for(i=1;i<=n;i++)a[i]=read();
90     Q=read();
91     Build(1,n,1);
92     for(i=1;i<=Q;i++){
93         q[i].L=read();q[i].R=read();q[i].id=i;
94     }
95     sort(q+1,q+Q+1);
96     solve();
97     return 0;
98 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章