zoukankan      html  css  js  c++  java
  • Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) F. Souvenirs 线段树套set

    F. Souvenirs

    题目连接:

    http://codeforces.com/contest/765/problem/F

    Description

    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 ≤ ri, s ≠ 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.

    Sample Input

    8
    3 1 4 1 5 9 2 6
    4
    1 8
    1 3
    4 8
    5 7

    Sample Output

    0
    1
    1
    3

    Hint

    题意

    给你n个数,查询区间(l,r)中,某两个l<=i,j<=r,且i!=r的,min(abs(a[i]-a[j]))这个值。

    题解:

    只有询问,显然就离线。

    最简单的做法是莫队+xxx,很容易做到nsqrt(n)logn的复杂度,当然这会TLE的。

    于是我们离线去,用线段树套set去维护这个最小值。

    每个线段树的节点,都维护一个set,存放的是这个区间的数。

    然后每次离线更新的时候,更新这个节点的最小值就好了。因为插入一个数,只会考虑这个数左边和右边的数是什么就好了。

    然后不断更新就行。

    这样复杂度是nlognlogn的。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+7;
    struct node{
        int l,r,id;
        bool operator<(const node& a)const{
            if(a.l==l&&a.r==r){
                return id<a.id;
            }
            if(a.l==l)
                return r<a.r;
            return l<a.l;
        }
    }query[maxn];
    struct Node{
        set<int> T;
        int mi;
    }T[maxn];
    int n,m,b[maxn],ans[maxn];
    void build(int x,int l,int r){
        T[x].mi=(1<<30);
        for(int i=l;i<=r;i++)
            T[x].T.insert(b[i]);
        if(l==r)return;
        int mid=(l+r)/2;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
    }
    int Query(int x,int l,int r,int L,int R){
        if(l>R||L>r)return (1<<30);
        if(L<=l&&r<=R)return T[x].mi;
        int mid=(l+r)/2;
        return min(Query(x<<1,l,mid,L,R),Query(x<<1|1,mid+1,r,L,R));
    }
    void upd(int x,int l,int r,int L,int R,int val,int &mi){
        if(l>R||L>r)return;
        if(l==r){
            T[x].mi=min(T[x].mi,abs(val-b[l]));
            mi=min(mi,T[x].mi);
            return;
        }
        set<int> &t = T[x].T;
        auto p = t.lower_bound(val);
        if((p==t.end()||(*p-val)>=mi)&&(p==t.begin()||(val-*(--p))>=mi)){
            mi=min(mi,Query(x,l,r,L,R));
            return;
        }
        int mid=(l+r)/2;
        upd(x<<1,l,mid,L,R,val,mi);
        upd(x<<1|1,mid+1,r,L,R,val,mi);
        T[x].mi=min(T[x<<1].mi,T[x<<1|1].mi);
    }
    void init(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&b[i]);
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
            scanf("%d%d",&query[i].l,&query[i].r),query[i].id=i;
    }
    int main(){
        init();
        sort(query+1,query+1+m);
        build(1,1,n);
        for(int i=m,l=n;i;i--){
            for(;l>=query[i].l;l--){
                int inf=(1<<30);
                upd(1,1,n,l+1,n,b[l],inf);
            }
            ans[query[i].id]=Query(1,1,n,query[i].l,query[i].r);
        }
        for(int i=1;i<=m;i++)
            cout<<ans[i]<<endl;
        return 0;
    }
  • 相关阅读:
    创建Maven web项目时 出现 web.xml is missing and <failOnMissingWebXml> is set to true错误 pox.xml编译错误
    警告: Hessian/Burlap: 'com.github.pagehelper.Page' is an unknown class in WebappClassLoader
    java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
    Project facet Java version 1.8 is not supported解决记录
    org.springframework.data.redis.RedisConnectionFailureException
    sql语句插入时提示:“Duplicate entry 'XXX' for key 1 ” 是什么原因?
    eclipse中文乱码解决方案
    第一个MapReduce的例子
    Java字节码—ASM
    JVM垃圾收集算法
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6405272.html
Copyright © 2011-2022 走看看