zoukankan      html  css  js  c++  java
  • P1712 [NOI2016] 区间 尺取法 线段树

    题意:

    戳这里

    分析:

    这个题目的限制条件只有两个:

    1. 选出 (m) 个相交的区间
    2. 求最大跟最小的差值

    我的第一反应是,按处理出每一个线段存在的范围,枚举交点,这样就满足了第一个条件,但是我发现这个第二个条件没法做呀,貌似没有什么数据结构能支持动态查询排名相差为 (m) 的两个数的差值的最小值,所以这个思路可以扔了

    我们发现其实限制更大的是第二个条件,所以我们考虑在满足第二个条件的前提下,尽量去满足第一个条件,那么我们按照区间的长度升序排序,双指针扫一遍,每当存在一个点被不小于 (m) 个区间覆盖之后,用双指针的右端点的长度减去左端点的长度,然后左端点++,这样在排序满足第二个条件,然后用一个数据结构维护区间最值满足第一个条件,直接上线段树就好了

    代码:

    #include<bits/stdc++.h>
    #define inl inline
    #define reg register
    #define mk(x,y) make_pair(x,y)
    #define lc rt<<1
    #define rc rt<<1|1
    #define fir first
    #define sec second
    
    using namespace std;
    
    namespace zzc
    {
        typedef long long ll;
        inl ll read()
        {
            ll x=0,f=1;char ch=getchar();
            while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
            while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
            return x*f;
        }
    
        const ll maxn = 1e6+5;
        ll n,m,ans=0x3f3f3f3f3f3f3f3f,cnt;
        ll val[maxn<<2],tag[maxn<<2],a[maxn],b[maxn],c[maxn<<1];
        pair<ll,pair<ll,ll> > p[maxn];
        
        inl void pushup(ll rt)
        {
            val[rt]=max(val[lc],val[rc]);
        }
    
        inl void pushdown(ll rt)
        {
            if(tag[rt])
            {
                val[lc]+=tag[rt];tag[lc]+=tag[rt];
                val[rc]+=tag[rt];tag[rc]+=tag[rt];
                tag[rt]=0;
            }
        }
    
        void modify(ll rt,ll l,ll r,ll ql,ll qr,ll k)
        {
            if(ql<=l&&r<=qr)
            {
                val[rt]+=k;
                tag[rt]+=k;
                return ;
            }
            ll mid=(l+r)>>1;
            pushdown(rt);
            if(ql<=mid) modify(lc,l,mid,ql,qr,k);
            if(qr>mid) modify(rc,mid+1,r,ql,qr,k);
            pushup(rt);
        }
    
        void work()
        {
            n=read();m=read();
            for(reg ll i=1;i<=n;i++)
            {
                a[i]=read();c[++cnt]=a[i];
                b[i]=read();c[++cnt]=b[i];
            }
            sort(c+1,c+cnt+1);
            cnt=unique(c+1,c+cnt+1)-c-1;
            for(reg ll i=1;i<=n;i++)
            {
                ll len=b[i]-a[i]+1;
                b[i]=lower_bound(c+1,c+cnt+1,b[i])-c;
                a[i]=lower_bound(c+1,c+cnt+1,a[i])-c;
                p[i]=mk(len,mk(a[i],b[i]));
            }
            sort(p+1,p+n+1);
            for(reg ll i=1,j=1;i<=n;i++)
            {
                modify(1,1,cnt,p[i].sec.fir,p[i].sec.sec,1);
                while(val[1]>=m)
                {
                    ans=min(ans,p[i].fir-p[j].fir);
                    modify(1,1,cnt,p[j].sec.fir,p[j].sec.sec,-1);
                    j++;
                }
            }
            if(ans==0x3f3f3f3f3f3f3f3f) puts("-1");
            else printf("%lld
    ",ans);
        }
    
    
    }
    
    int main()
    {
        zzc::work();
        return 0;
    }
    
  • 相关阅读:
    swift 第十四课 可视化view: @IBDesignable 、@IBInspectable
    swift 第十三课 GCD 的介绍和使用
    swift 第十二课 as 的使用方法
    swift 第十一课 结构体定义model类
    swift 第十课 cocopod 网络请求 Alamofire
    swift 第九课 用tableview 做一个下拉菜单Menu
    swift 第八课 CollectView的 添加 footerView 、headerView
    swift 第七课 xib 约束的优先级
    swift 第六课 scrollview xib 的使用
    swift 第五课 定义model类 和 导航栏隐藏返回标题
  • 原文地址:https://www.cnblogs.com/youth518/p/14384080.html
Copyright © 2011-2022 走看看