zoukankan      html  css  js  c++  java
  • 【BZOJ4653】【Noi2016D2】区间

    原题传送门

    Description

    在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn]。现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri。
    对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值。
    求所有合法方案中最小的花费。如果不存在合法的方案,输出 −1。

    Input

    第一行包含两个正整数 n,m用空格隔开,意义如上文所述。
    接下来 n行,每行表示一个区间,包含用空格隔开的两个整数 li 和 ri 为该区间的左右端点。

    Output

    只有一行,包含一个正整数,即最小花费。

    Sample Input

    6 3
    3 5
    1 2
    3 4
    2 2
    1 5
    1 4

    Sample Output

    2

    Hint

    保证 1≤m≤n,N<=500000,M<=200000,0≤li≤ri≤10^9
    Time Limit : 3s ,Memory Limit: 256MB.

    Solution

    首先考虑如何处理区间共同包含至少一个位置这一问题,显然可以利用线段树来解决,由于区间范围较大,因此需要离散后处理。
    接下来考虑最长区间长度减去选中的最短区间长度,并且挑选m个,这一问题,根据最长-最短这一性质,以及数据范围,容易推断出将区间按长度排序后,利用头尾指针进行维护,将其间的所有区间加入线段树,只需要判断是否存在点被覆盖不少于m次的情况即可。
    时间效率$ O(n log_{2} n) $.

    Code

    #include <stdio.h>
    #include <algorithm>
    #define MN 500005
    #define M (1<<20)
    #define R register
    #define mid (l+r>>1)
    #define inf 0x3f3f3f3f
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read(){
        R int x; R bool f; R char c;
        for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-');
        for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0');
        return f?-x:x;
    }
    int l[MN],r[MN],len[MN],T[M<<1],mark[M<<1],m,n,rk[MN],val[MN<<1],cnt=1,ans=inf;
    inline bool cmp(int a,int b){return len[a]>len[b];}
    inline int findpos(int k){
        R int l=1,r=cnt;    while(l<r)
            if (val[mid]<k) l=mid+1;
            else r=mid; return l;
    }
    inline void add(int k,int p){T[k]+=p,mark[k]+=p;}
    inline void pushdown(int k){if (!mark[k]) return;add(k<<1,mark[k]);add(k<<1|1,mark[k]);mark[k]=0;}
    inline void modify(int k,int l,int r,int a,int b,int ad){
        if (l>=a&&r<=b) {add(k,ad); return;};pushdown(k);
        if (a<=mid) modify(k<<1,l,mid,a,b,ad);
        if (b>mid) modify(k<<1|1,mid+1,r,a,b,ad);
        T[k]=max(T[k<<1],T[k<<1|1]);
    }
    int main(){
        n=read(),m=read();
        for (R int i=1; i<=n; ++i) l[i]=read(),r[i]=read(),len[i]=r[i]-l[i],rk[i]=i,val[(i-1)<<1|1]=l[i],val[i<<1]=r[i];
        std::sort(val+1,val+(n<<1)+1);std::sort(rk+1,rk+n+1,cmp);
        for (R int i=2; i<=(n<<1); ++i) if (val[i]!=val[i-1]) val[++cnt]=val[i];
        for (R int i=1; i<=n; ++i) l[i]=findpos(l[i]),r[i]=findpos(r[i]);
        for (R int h=1,t=1; t<=n; ++t)
            for (modify(1,1,cnt,l[rk[t]],r[rk[t]],1); T[1]>=m; ans=min(ans,len[rk[h]]-len[rk[t]]),modify(1,1,cnt,l[rk[h]],r[rk[h++]],-1));
        printf("%d
    ",(ans==inf)?-1:ans);return 0;
    }
    
  • 相关阅读:
    Scale-Invariant Error
    Regularizing Deep Networks with Semantic Data Augmentation
    BBN: Bilateral-Branch Network with Cumulative Learning for Long-Tailed Visual Recognition
    2021.5.17
    2021.5.14
    2021.5.13
    2021.5.12
    2021.5.8
    2021.5.7 团队冲刺第十天
    2021.5.6 团队冲刺第九天
  • 原文地址:https://www.cnblogs.com/Melacau/p/BZOJ4653.html
Copyright © 2011-2022 走看看