• 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;
    }
    
  • 相关阅读:
    02Golang 初识包管理
    mongo append列表元素变 extend列表元素
    linux常用命令
    EA Desktop 修改安装路径
    离线部署MySQL5.6
    分析服务器日志命令
    在事件中使用useRoute、useRouter注意事项
    datasnap 指定 npm 打包文件目录
    css练手 tabs选项卡切换
    css 练手 下拉菜单
  • 原文地址:https://www.cnblogs.com/youth518/p/14384080.html
Copyright © 2020-2023  润新知