zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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 }
  • 相关阅读:
    【Lucene3.6.2入门系列】第14节_SolrJ操作索引和搜索文档以及整合中文分词
    最短路--Dijkstra算法 --HDU1790
    XMPPFrameWork IOS 开发(六)聊天室
    InfoSphere BigInsights 安装部署
    EXCEL VBA运行不显示系统提示
    android 随手记 倒计时
    Conversion between json and object
    java 运行项目不放到tomcat下的webapps文件夹下放到自己建的文件夹中的处理办法
    sBPM产品介绍
    linux进程,作业,守护进程,进程间同步
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7097861.html
Copyright © 2011-2022 走看看