C34 线段树+双指针 P1712 [NOI2016] 区间

视频链接:220 线段树+双指针 [NOI2016] 区间_哔哩哔哩_bilibili

 

 

Luogu P1712 [NOI2016] 区间

复制代码
// 线段树+双指针+离散化
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

#define ls u<<1
#define rs u<<1|1
const int N=500005;
int n,m;
struct line{
  int l,r,len;
  bool operator<(line &b){
    return len<b.len;
  }
}L[N];      //区间
int X[N*2]; //X坐标
struct tree{
  int l,r,cnt,lazy;//重叠数,懒标记
}t[N*2*4];  //线段树

void pushup(int u){   //上传
  t[u].cnt=max(t[ls].cnt,t[rs].cnt);
}
void pushdown(int u){ //下传
  if(t[u].lazy){
    t[ls].cnt+=t[u].lazy;
    t[rs].cnt+=t[u].lazy;
    t[ls].lazy+=t[u].lazy;
    t[rs].lazy+=t[u].lazy;
    t[u].lazy=0;
  }
}
void build(int u,int l,int r){ //建树
  t[u]={l,r};
  if(l==r) return;
  int mid=(l+r)>>1;
  build(ls,l,mid);
  build(rs,mid+1,r);
}
void change(int u,int l,int r,int k){
  if(l>t[u].r||t[u].l>r) return;
  if(l<=t[u].l && t[u].r<=r){
    t[u].cnt+=k;
    t[u].lazy+=k;
    return;
  }
  pushdown(u);
  change(ls,l,r,k);
  change(rs,l,r,k);
  pushup(u);
}
int main(){
  scanf("%d%d",&n,&m);
  for(int i=1; i<=n; i++){
    int a,b; scanf("%d%d",&a,&b);
    X[i]=a; X[i+n]=b;
    L[i]={a,b,b-a};
  }
  sort(L+1,L+n+1);  //按长度排序
  sort(X+1,X+n*2+2);              //排序
  int k=unique(X+1,X+n*2+1)-X-1;  //去重
  for(int i=1; i<=n; i++){        //离散化
    L[i].l=lower_bound(X+1,X+k+1,L[i].l)-X;
    L[i].r=lower_bound(X+1,X+k+1,L[i].r)-X;
  }
  build(1,1,k); //k最大是2*n
  int ans=1e9;
  for(int i=0,j=0; j<=n;){    //双指针
    while(t[1].cnt<m && j<=n)
      j++, change(1,L[j].l,L[j].r,1);
    if(t[1].cnt<m) break;     //无解
    while(t[1].cnt==m && i<=j)
      i++, change(1,L[i].l,L[i].r,-1);
    ans=min(ans,L[j].len-L[i].len);
  }
  printf("%d",ans==1e9?-1:ans);
}
复制代码

 

posted @   董晓  阅读(315)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-09-20 G10 筛法求约数个数
点击右上角即可分享
微信分享提示