zoukankan      html  css  js  c++  java
  • [NOI2016]区间-线段树

    一道很巧妙的题。

    首先我们需要解决的问题,怎么快速判断选出的m个区间是否存在交。

    我们反过来考虑这个问题,

    我们每一个选出的区间,就对应的在线段树上区间加1,那么只要存在最大值等于m,就一定有m个区间满足条件了。

    那么把区间从小到大排序,一直加到最大值等于m,更新答案,然后删掉最小区间,不停的做下去就好了。

    #include <bits/stdc++.h>
    #define lson p<<1
    #define rson (p<<1)|1
    using namespace std;
    inline int gi () {
        int x=0, w=0; char ch=0;
        while (! (ch>='0' && ch<='9') ) {
        if (ch=='-') w=1;
        ch=getchar ();
        }
        while (ch>='0' && ch<='9') {
        x= (x<<3) + (x<<1) +  (ch^48);
        ch=getchar ();
        }
        return w?-x:x;
    }
    
    const int N=5e5+10;
    int n,m,head=1,Ans=0x3f3f3f3f,Num,Ls[N<<1],LS[N<<1],Cnt[N<<3],Tag[N<<3];
    
    struct Sect {
        int l, r, val;
    }s[N];
    bool Cmp (Sect a, Sect b) {
        return a.val<b.val;
    }
    
    void Pushup (int p) {
        Cnt[p]=max (Cnt[lson], Cnt[rson]);
    }
    
    void Pushdown (int p) {
        if (!Tag[p]) return;
        Tag[lson]+=Tag[p];
        Tag[rson]+=Tag[p];
        Cnt[lson]+=Tag[p];
        Cnt[rson]+=Tag[p];
        Tag[p]=0;
    }
    
    void Modify (int p, int l, int r, int Ml, int Mr, int val) {
        if (l>=Ml && Mr>=r) {
        Cnt[p]+=val;
        Tag[p]+=val;
        return;
        }
        Pushdown (p);
        int Mid= (l+r) >> 1;
        if (Ml<=Mid) Modify (lson, l, Mid, Ml, Mr, val);
        if (Mr>Mid) Modify (rson, Mid+1, r, Ml, Mr, val);
        Pushup (p);
    }
    
    int main ()
    {
        n=gi (), m=gi ();
        memset (Ls, -1, sizeof (Ls) );
        memset (LS, -1, sizeof (LS) );
        for (int i=1;i<=n;++i) {
        s[i].l=gi (), s[i].r=gi ();
        s[i].val=s[i].r-s[i].l;
        Ls[++Num]=s[i].l, Ls[++Num]=s[i].r;
        }
        sort (Ls+1, Ls+Num+1);
        for (int i=1, j=0;i<=Num;++i) {
        if (Ls[i]!=Ls[i-1]) LS[++j]=Ls[i];
        if (i==Num) {
            Num=j;
            break;
        }
        }
        for (int i=1;i<=n;++i) {
        s[i].l=lower_bound (LS+1, LS+Num+1, s[i].l) -LS;
        s[i].r=lower_bound (LS+1, LS+Num+1, s[i].r) -LS;
        }    
        sort (s+1, s+n+1, Cmp);
        for (int i=1;i<=n;++i) {
        Modify (1, 1, Num, s[i].l, s[i].r, 1);            
        while (Cnt[1]==m) {
            Ans=min (Ans, s[i].val-s[head].val);
            Modify (1, 1, Num, s[head].l, s[head].r, -1);
            head++;
        }
        }
        printf ("%d
    ", Ans==0x3f3f3f3f?-1:Ans);
        return 0;
    }
    BY BHLLX
  • 相关阅读:
    投资人的能量往往大多远远不仅于此,他能站在不同的角度和高度看问题(要早点拿投资,要舍得让出股份)——最好不要让 Leader 一边做技术、一边做管理,人的能力是有限的,精力也是有限的
    汇编实现获取CPU信息
    Web service的学习资源
    重启网卡的几种方法(命令行,API,
    认知服务
    平台化项目多语言架构
    移动跨平台开发框架Ionic开发一个新闻阅读APP
    net core 1.0 实现负载多服务器单点登录
    canvas1
    asp.net core + angular2
  • 原文地址:https://www.cnblogs.com/Bhllx/p/9930296.html
Copyright © 2011-2022 走看看