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;
    }
    
  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/youth518/p/14384080.html
Copyright © 2011-2022 走看看