• [NOI2016]区间


    链接:https://www.luogu.org/problemnew/show/P1712

    题解:

    显然是个滑动窗口的问题,用线段树维护最大值即可

    注意:离散化时空间要开2倍,最大值初始赋值为2e9比较好

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 500100
    #define mm 1999999999
    #define lll long long
    lll n,m;
    struct re{
        lll a,b,len,c,d;
    }a[maxn],b[maxn*2];
    bool cmp(re x,re y)
    {
      if (x.len>y.len) return(true); else return(false);    
    } 
    struct ree
    {
        lll h,t,x,lazy;
    }p[maxn*4];
    void updata(lll x)
    {
        p[x].x=max(p[x*2].x,p[x*2+1].x);
    }
    #define mid (h+t)/2
    void build(lll x,lll h,lll t)
    {
        p[x].h=h; p[x].t=t;
        p[x].x=0; p[x].lazy=0;
        if (h==t) return;
        build(x*2,h,mid); build(x*2+1,mid+1,t);
    }
    void down(lll x)
    {
        if (p[x].lazy)
        {
            p[x].x+=p[x].lazy;
            if (p[x].h!=p[x].t)
            {
                p[x*2].lazy+=p[x].lazy;
                p[x*2+1].lazy+=p[x].lazy;
            }
            p[x].lazy=0;
        }
    }
    void change (lll x,lll h,lll t,lll sum)
    {
        down(x);
        if (p[x].h>t||p[x].t<h) return;
        if (h<=p[x].h&&p[x].t<=t)
        {
            p[x].lazy+=sum; down(x);
            return;
        }
        change(x*2,h,t,sum);change(x*2+1,h,t,sum);
        updata(x);
    }
    lll query(lll x,lll h,lll t)
    {
        down(x);
        if (p[x].h>t||p[x].t<h) return(0);
        if (h<=p[x].h&&p[x].t<=t)
        {
            return(p[x].x);
        }
        return(max(query(x*2,h,t),query(x*2+1,h,t)));
    }
    int main()
    {
      ios::sync_with_stdio(false);
      cin>>n>>m;
      for (lll i=1;i<=n;i++)
      {
          cin>>a[i].a>>a[i].b;
          a[i].len=a[i].b-a[i].a;
      }
      sort(a+1,a+1+n,cmp);
      for (lll i=1;i<=n;i++)
      {
          b[i*2-1].a=i*2-1; b[i*2].a=i*2;
          b[i*2-1].len=a[i].a; b[i*2].len=a[i].b;
      }    
      sort(b+1,b+2*n+1,cmp);
      lll ll=0; b[0].len=-mm;
      for (lll i=1;i<=2*n;i++)
      {
          if (b[i].len!=b[i-1].len) ll++;
          if (b[i].a%2==0) a[(b[i].a-1)/2+1].c=ll;
          else a[(b[i].a-1)/2+1].d=ll;
      }
      build(1,1,ll);
      lll h=0,t=0;
      lll ans=mm;
      //for (lll i=1;i<=2*n;i++) cout<<b[i].len<" ";
      //for (lll i=1;i<=n;i++) cout<<endl<<a[i].a<<" "<<a[i].b<<" "<<a[i].c<<" "<<a[i].d; 
      while (t<n)
      {
          h++;
          if (h!=1)
          {
          change(1,a[h-1].c,a[h-1].d,-1);    
        }
          while (query(1,1,ll)<m&&t<=n)
          {
              t++; change(1,a[t].c,a[t].d,1);
        }
        if (t<=n) ans=min(ans,a[h].len-a[t].len);
      }
      if (ans!=mm)cout<<ans; else cout<<-1;
    } 
  • 相关阅读:
    Win10或Win8下ObjectARX2015 Wizard向导创建项目失败解决方法
    对用友二次开发的初次认识
    我对asp.net管道模型的理解
    wblockCloneObjects 写块克隆的使用
    acedCommand 之使用镜像命令
    MFC之动态调用自己写的类库中的类的成员方法
    objectarx 天正的墙转梁线
    objectarx 之让用户自定义插件命令
    MFC之多字节和宽字节的总结
    MFC之使用blat发送邮件
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8398446.html
Copyright © 2020-2023  润新知