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 }

 

posted @ 2017-06-30 11:00  SilverNebula  阅读(373)  评论(0编辑  收藏  举报
AmazingCounters.com