zoukankan      html  css  js  c++  java
  • bzoj4653: [Noi2016]区间

    嗯这道题又涨姿势了。第一次看见这样的离散化。。666

    说说做法吧,第一眼就看出线段树的说,贪心没看出来。。就只能膜网上的题解了,我们先将长度给排序一下,然后看看从当前位置(L)开始,要到哪个点(R)就可以达到m个区间共同包含至少一个位置,这就是一种解,判断m个区间的方式就是利用线段树维护一个区间最大值。对于那些没有贡献的区间,插入也不影响操作,因为L~R之间的不是最值,对答案没有影响。

    #include<set>
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,m;
    struct Seg
    {
        int l,r,lc,rc,c,u;
    }tr[2100000];int trlen;
    void bt(int l,int r)
    {
        trlen++;int now=trlen;
        tr[now].l=l;tr[now].r=r;
        tr[now].c=0;tr[now].u=0;
        tr[now].lc=tr[now].rc=-1;
        if(l<r)
        {
            int mid=(l+r)/2;
            tr[now].lc=trlen+1;bt(l,mid);
            tr[now].rc=trlen+1;bt(mid+1,r);
        }
    }
    void inherit(int now,int k)
    {
        tr[now].c+=k;tr[now].u+=k;
    }
    void change(int now,int l,int r,int k)
    {
        if(tr[now].l==l&&tr[now].r==r){inherit(now,k);return ;}
        
        int lc=tr[now].lc,rc=tr[now].rc;
        if(tr[now].u!=0)
        {
            inherit(lc,tr[now].u);
            inherit(rc,tr[now].u);
            tr[now].u=0;
        }
        
        int mid=(tr[now].l+tr[now].r)/2;
             if(r<=mid)  change(lc,l,r,k);
        else if(mid+1<=l)change(rc,l,r,k);
        else
        {
            change(lc,l,mid,k);
            change(rc,mid+1,r,k);
        }
        tr[now].c=max(tr[lc].c,tr[rc].c);
    }
    struct lr
    {
        int l,r,s;
    }a[510000],b[510000];
    int lslen,ls[1100000];
    bool cmp(lr n1,lr n2)
    {
        if(n1.s<n2.s||(n1.s==n2.s&&n1.l<=n2.l))return true;
        return false;
    }
    void LSH()
    {
        lslen=0;
        for(int i=1;i<=n;i++)
        {
            ls[++lslen]=a[i].l;
            ls[++lslen]=a[i].r;
        }
        sort(ls+1,ls+1+lslen);
        lslen=unique(ls+1,ls+1+lslen)-ls-1;
        for(int i=1;i<=n;i++)
        {
            b[i].l=lower_bound(ls+1,ls+lslen+1,a[i].l)-ls;
            b[i].r=lower_bound(ls+1,ls+lslen+1,a[i].r)-ls;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].s=a[i].r-a[i].l;
        }
        sort(a+1,a+1+n,cmp);
        LSH();
        trlen=0;bt(1,lslen);
        int L=1,R=0,ans=2147483647;
        while(L<=n)
        {
            while(R<n&&tr[1].c<m)
            {
                R++;
                change(1,b[R].l,b[R].r,1);
            }
            if(tr[1].c>=m)ans=min(ans,a[R].s-a[L].s);
            change(1,b[L].l,b[L].r,-1);L++;
        }
        if(ans==2147483647)printf("-1
    ");
        else printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    解决ORACLE存储过程锁定的问题
    #{propName,attr1=val1,attr2=val2}
    集成confluence与jira
    jira4.1.1安装
    Mac OS X 10.6下安装MySQL 5.1.45
    JIRA+MySQL配置
    xcode4.5 iOS6 cocos2dx 横屏解决方案
    gSoap
    Jira5.0.2安装及破解
    MFC中显示cocos2dx
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/7634674.html
Copyright © 2011-2022 走看看