• BZOJ4653


    Portal

    Description

    给出数轴上的(n(nleq5 imes10^5))个闭区间,从中选出(m(mleq2 imes10^5))个,并且它们的交集不为空。一个合法方案的代价为所选区间中的最长长度减去最短长度,求最小代价。

    Solution

    将区间按长度由小到大排序。每次钦定区间(i)为最短区间,然后寻找(jgeq i)使得存在至少一个数被区间(i..j)中的(m)个覆盖,这可以用线段树实现。因为(j)是不退的,所以循环(i=1..n),每次向后寻找(j)即可。

    时间复杂度(O(nlogn))

    Code

    //[NOI2016]区间
    #include <algorithm>
    #include <cstdio>
    #include <queue>
    using namespace std;
    inline char gc()
    {
        static char now[1<<16],*s,*t;
        if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
        return *s++;
    }
    inline int read()
    {
        int x=0; char ch=gc();
        while(ch<'0'||'9'<ch) ch=gc();
        while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
        return x;
    }
    int const N=1e6+10;
    int n,m; int n0,map[N];
    struct range{int L,R;} r[N>>1];
    bool cmpRng(range x,range y) {return x.R-x.L<y.R-y.L;}
    #define Ls (p<<1)
    #define Rs ((p<<1)|1)
    int rt; int maxV[N<<2],tag[N<<2];
    int L,R;
    void update(int p) {maxV[p]=max(maxV[Ls],maxV[Rs]);}
    void add(int p,int x) {maxV[p]+=x,tag[p]+=x;}
    void pushdw(int p) {if(tag[p]) add(Ls,tag[p]),add(Rs,tag[p]),tag[p]=0;}
    void ins(int p,int L0,int R0,int x)
    {
        if(L<=L0&&R0<=R) {add(p,x); return;}
        pushdw(p);
        int mid=L0+R0>>1;
        if(L<=mid) ins(Ls,L0,mid,x);
        if(mid<R) ins(Rs,mid+1,R0,x);
        update(p);
    }
    int query(int p,int L0,int R0)
    {
        if(L<=L0&&R0<=R) return maxV[p];
        pushdw(p);
        int mid=L0+R0>>1; int res=0;
        if(L<=mid) res=max(res,query(Ls,L0,mid));
        if(mid<R) res=max(res,query(Rs,mid+1,R0));
        return res;
    }
    int main()
    {   
        n=read(),m=read();
        for(int i=1;i<=n;i++) map[i*2-1]=r[i].L=read(),map[i*2]=r[i].R=read();
        sort(r+1,r+n+1,cmpRng);
        sort(map+1,map+n+n+1); n0=unique(map+1,map+n+n+1)-map-1;
        for(int i=1;i<=n;i++) r[i].L=lower_bound(map+1,map+n0+1,r[i].L)-map;
        for(int i=1;i<=n;i++) r[i].R=lower_bound(map+1,map+n0+1,r[i].R)-map;
        int ans=2e9; rt=1;
        for(int i=1,j=0;i<=n;i++)
        {
            while(true)
            {
                if(maxV[rt]>=m) break;
                if(++j>n) break;
                L=r[j].L,R=r[j].R,ins(rt,1,n0,1);
            }
            if(j>n) break;
            ans=min(ans,(map[r[j].R]-map[r[j].L])-(map[r[i].R]-map[r[i].L]));
            L=r[i].L,R=r[i].R; ins(rt,1,n0,-1);
        }
        if(ans==2e9) puts("-1");
        else printf("%d
    ",ans);
        return 0;
    }
    

    P.S.

    我菜死了...其实很简单的,也做过类似的题

  • 相关阅读:
    “阿基里斯与乌龟”的终结性思考
    这个世界本来的样子
    Seven times have I despised my soul 《我曾七次鄙视自己的灵魂》
    Youth is not a time of life, it is a state of mind.
    对于过去所犯的错误,最好的道歉是在将来做正确的事
    使用UltraISO刻录自己的音乐CD步骤
    为什么一个目录里放超过十个Mp4文件会导致资源管理器和播放程序变卡变慢?
    用Perl发送邮件小例子
    用df命令显示磁盘使用量和占用率。
    三个JS函数闭包(closure)例子
  • 原文地址:https://www.cnblogs.com/VisJiao/p/BZOJ4653.html
Copyright © 2020-2023  润新知