正题

题目链接:https://www.luogu.com.cn/problem/P1712


题目大意

\(n\)个区间,求出其中\(m\)个区间使得它们有覆盖同一个点且最长区间长度减去最短长度最小。


解题思路

因为是最接近的\(m\)个,考虑一种叫尺取法的做法。

先把区间按照长度排序,每次加入一个区间直到满足有位置被覆盖不少于\(m\)次,然后统计答案后不断弹出末尾区间直到没有区间出现不少于\(m\)次。

用线段树维护就好了,懒得动态开点就写了个离散化。

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e5+10;
int n,m,l[N],r[N],b[N<<1],p[N];
int w[N<<4],lazy[N<<4],ans;
bool cmp(int x,int y)
{return r[x]-l[x]<r[y]-l[y];}
void Downdata(int x){
if(!lazy[x])return;
w[x*2]+=lazy[x];w[x*2+1]+=lazy[x];
lazy[x*2]+=lazy[x];lazy[x*2+1]+=lazy[x];
lazy[x]=0;return;
}
void Change(int x,int L,int R,int l,int r,int val){
if(L==l&&R==r){w[x]+=val;lazy[x]+=val;return;}
int mid=(L+R)>>1;Downdata(x);
if(r<=mid)Change(x*2,L,mid,l,r,val);
else if(l>mid)Change(x*2+1,mid+1,R,l,r,val);
else Change(x*2,L,mid,l,mid,val),Change(x*2+1,mid+1,R,mid+1,r,val);
w[x]=max(w[x*2],w[x*2+1]);
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&l[i],&r[i]);
b[i]=l[i];b[i+n]=r[i];
p[i]=i;
}
sort(b+1,b+1+2*n);
sort(p+1,p+1+n,cmp);
int cnt=unique(b+1,b+1+2*n)-b-1;
int t=1;ans=2147483647;
int x,y=p[1];
for(int i=1;i<=n;i++){
x=p[i];y=p[t];
l[x]=lower_bound(b+1,b+1+cnt,l[x])-b;
r[x]=lower_bound(b+1,b+1+cnt,r[x])-b;
Change(1,1,cnt,l[x],r[x],1);
if(w[1]>=m){
while(w[1]>=m)
Change(1,1,cnt,l[p[t]],r[p[t]],-1),t++;
ans=min(ans,(b[r[x]]-b[l[x]])-(b[r[p[t-1]]]-b[l[p[t-1]]]));
}
}
if(ans>=2147483647)puts("-1");
else printf("%d\n",ans);
return 0;
}

P1712-[NOI2016]区间【线段树,尺取法】的更多相关文章

  1. Luogu P1712 [NOI2016]区间(线段树)

    P1712 [NOI2016]区间 题意 题目描述 在数轴上有 \(N\) 个闭区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\) .现在要从中选出 \(M\) 个区间, ...

  2. luogu 1712 区间(线段树+尺取法)

    题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭 ...

  3. 洛谷$P1712\ [NOI2016]$区间 线段树

    正解:线段树 解题报告: 传送门$QwQ$ $umm$很久以前做的了来补个题解$QwQ$ 考虑给每个区间按权值($r-l$从大往小排序,依次加入,然后考虑如果有一个位置被覆盖次数等于$m$了就可以把权 ...

  4. 2018.08.17 bzoj4653: [Noi2016]区间(线段树+尺取法)

    传送门 将坐标离散化之后直接用尺取法(双指针)+线段树维护. 其实就是说只要目前所有点的被覆盖次数是大于等于m的就移动左指针删除区间更新答案,否则移动右指针加入区间更新答案. 话说忘记排序以及建树的时 ...

  5. 【NOI2016】区间 题解(线段树+尺取法)

    题目链接 题目大意:给定$n$个区间$[l_i,r_i]$,选出$m$个区间使它们有一个共同的位置$x$,且使它们产生的费用最小.求最小费用.费用定义为最长的区间长度减去最短区间长度. ------- ...

  6. [NOI2016]区间 线段树

    [NOI2016]区间 LG传送门 考虑到这题的代价是最长边减最短边,可以先把边按长度排个序,双指针维护一个尺取的过程,如果存在包含某个点的区间数\(\ge m\),就更新答案并把左指针右移,这样做的 ...

  7. BZOJ4653 [NOI2016]区间 [线段树,离散化]

    题目传送门 区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就 ...

  8. UOJ222 NOI2016 区间 线段树+FIFO队列

    首先将区间按长度排序后离散化端点(这里的“长度”指的是离散化之前区间的实际长度) 然后模拟一个队列,区间按排好的顺序依次进入,直到某个点被覆盖了M次.之后依次出队,直到所有点都被覆盖小于M次 修改和询 ...

  9. BZOJ.4653.[NOI2016]区间(线段树)

    BZOJ4653 UOJ222 考虑二分.那么我们可以按区间长度从小到大枚举每个区间,对每个区间可以得到一个可用区间长度范围. 我们要求是否存在一个点被这些区间覆盖至少\(m\)次.这可以用线段树区间 ...

随机推荐

  1. C#基础知识---is与as

    一.is与as对比 is检查一个对象是否兼容于指定的类型,并返回一个Boolean值:true或者fasle. 注:is操作符永远不会抛出异常 经常按如下方法使用: ClassA { .... } O ...

  2. C语言实现类似C++的容器vector

    C语言也能面向对象?不是C++是面向对象的么?其实C语言也能抽象成简单的面向对象方法,在Linux内核源码当中,底层的驱动代码.文件系统等皆采用了面向对象的封装技术,这样的好处是将客观的东西抽象出来, ...

  3. Java静态内部类——重点是精妙的demo

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/cd18333612683/article/details/79129503什么是内部类大部分时候,类 ...

  4. sparksql字段类型转换

    1.spark sql 计算时,一定要注意精度的问题,一般像金额之类的值,要先转换为double或者 decimal来进行计算了. 一.sql的方式:select shop_id,order_id,s ...

  5. 移动端动画——requestAnimationFrame

    window.requestAnimationFrame() 告诉浏览器--你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画.该方法需要传入一个回调函数作为参数,该回调函数会 ...

  6. Learning ROS: Running ROS across multiple machines

    Start the master ssh hal roscore Start the listener ssh hal export ROS_MASTER_URI=http://hal:11311 r ...

  7. win7上帝模式详解

    最近,Windows7"GodMode"(上帝模式)被国内各大网站和论坛炒得沸沸扬扬."GodMode"始见于国外网站"GeekInDisguise& ...

  8. sublime text 的 Ctrl + P「模糊搜索算法」

    Reverse Engineering Sublime Text's Fuzzy Match 这是我能 google 到的最早的一篇关于 Sublime Text 的模糊搜索的文章. https:// ...

  9. 简单C++线程池

    简单C++线程池 Java 中有一个很方便的 ThreadPoolExecutor,可以用做线程池.想找一下 C++ 的类似设施,尤其是能方便理解底层原理可上手的.网上找到的 demo,基本都是介绍的 ...

  10. TypeScript 中函数的理解?与 JavaScript 函数的区别?

    一.是什么 函数是JavaScript 应用程序的基础,帮助我们实现抽象层.模拟类.信息隐藏和模块 在TypeScript 里,虽然已经支持类.命名空间和模块,但函数仍然是主要定义行为的方式,Type ...