zoukankan      html  css  js  c++  java
  • codeforces 765 F Souvenirs 线段树+set

    题意:多次询问区间内 两数差的绝对值的最小值

    题解:离线询问则可以按照询问的l排序,倒着询问,倒着从r更新到l 每次更新i+1到n这个区间,保证这次的更新不会影响到下一次以及以后的更新。因为当两个区间出现覆盖时,l更小的那个区间的值一定小于等于另一个,画个图就可以明白。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    #include <cstring>
    #include <iomanip>
    #include <set>
    #include<ctime>
    #include<unordered_map>
    //CLOCKS_PER_SEC
    #define se second
    #define fi first
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define Pii pair<int,int>
    #define Pli pair<ll,int>
    #define ull unsigned long long
    #define pb push_back
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    const int N=1e6+10;
    const ull base=163;
    const int INF=0x3f3f3f3f;
    using namespace std;
    struct node {
        set<int>s;
        int mi;
    }T[N<<2];
    struct que {
        int l,r,id;
    }q[N<<2];
    int a[N];
    bool cmp(que a,que b){
        if(a.l==b.l&&a.r==b.r)return a.id<b.id;
        if(a.l==b.l)return a.r<=b.r;
        return a.l<b.l;
    }
    void build(int l,int r,int rt){
        T[rt].mi=INF;
        for(int i=l;i<=r;i++)T[rt].s.insert(a[i]);
        if(l==r)return ;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    int query(int l,int r,int rt,int L,int R){
        if(l>R||L>r)return INF;
        if(L<=l&&R>=r){
            return T[rt].mi;
        }
        int m=(l+r)>>1;
        return min(query(lson,L,R),query(rson,L,R));
    }
    void update(int l,int r,int rt,int L,int R,int v,int &mi){
        if(l>R||L>r)return ;
        if(l==r){
            T[rt].mi=min(T[rt].mi,abs(a[l]-v));
            mi=min(mi,T[rt].mi);
            return ;
        }
        set<int> &t=T[rt].s;
        auto p=t.lower_bound(v);
        if((p==t.end()||*p-v>=mi)&&(p==t.begin()||v-*(--p)>=mi)){
            mi=min(mi,query(l,r,rt,L,R));
            return ;
        }
        int m=(l+r)>>1;
        update(lson,L,R,v,mi);
        update(rson,L,R,v,mi);
        T[rt].mi=min(T[rt<<1].mi,T[rt<<1|1].mi);
    }
    int ans[N];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        int m;scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        build(1,n,1);
        sort(q+1,q+1+m,cmp);
        for(int i=m,l=n;i>=0;i--){
            for(;l>=q[i].l;l--){
                int tmp=INF;
                update(1,n,1,l+1,n,a[l],tmp);
            }
            ans[q[i].id]=query(1,n,1,q[i].l,q[i].r);
        }
        for(int i=1;i<=m;i++){
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    等待队列设备[置顶] Linux设备驱动,等待队列
    宠物功能[置顶] QQ宠物保姆
    选中拖动Unity3D系列教程–使用免费工具在Unity3D中开发2D游戏 第二节(下)
    序列化对象java中为什么要实现序列化,什么时候实现序列化?
    函数表达式[置顶] 母函数详解
    文件问题cocos2dx&cocosbuilder折腾记
    模块functionJavaScript学习笔记(二十五) 沙箱模式
    nullnullflume ng配置拓扑图
    对象序列化对象的序列化和反序列化
    扩展编程PHP自学之路PHP数据库编程
  • 原文地址:https://www.cnblogs.com/Mrleon/p/9097557.html
Copyright © 2011-2022 走看看