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 }
  • 相关阅读:
    wince嵌入式应用程序开发环境搭建
    用户 'NT AUTHORITY\NETWORK SERVICE' 登录失败
    git# 建立个人级服务器仓库 git init bare
    Bind和Eval的区别详解
    控件包含代码块(即 <% ... %>),因此无法修改控件集合 (转自http://blog.csdn.net/wangchao1982/archive/2007/11/19/1892472.aspx)
    Sys.ArgumentOutOfRangeException: Value must be an integer 错误的原因
    判断Cookies是否处于开启状态
    多个解决方案引用同一工程文件时冲突的解决方法
    javascript无提示的关闭页面
    Server.MapPath()
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7097861.html
Copyright © 2011-2022 走看看