题目描述

在数轴上有 NN 个闭区间 [l_1,r_1],[l_2,r_2],...,[l_n,r_n][l1​,r1​],[l2​,r2​],...,[ln​,rn​] 。现在要从中选出 MM 个区间,使得这 MM 个区间共同包含至少一个位置。换句话说,就是使得存在一个 xx ,使得对于每一个被选中的区间 [l_i,r_i][li​,ri​] ,都有 l_i≤x≤r_ili​≤x≤ri​ 。

对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [l_i,r_i][li​,ri​] 的长度定义为 r_i-l_iri​−li​ ,即等于它的右端点的值减去左端点的值。

求所有合法方案中最小的花费。如果不存在合法的方案,输出 -1−1 。

输入输出格式

输入格式:

第一行包含两个正整数 N,MN,M 用空格隔开,意义如上文所述。保证 1≤M≤N1≤M≤N

接下来 NN 行,每行表示一个区间,包含用空格隔开的两个整数 l_ili​ 和 r_iri​ 为该区间的左右端点。

N<=500000,M<=200000,0≤li≤ri≤10^9N<=500000,M<=200000,0≤li≤ri≤109

输出格式:

只有一行,包含一个正整数,即最小花费。

输入输出样例

输入样例#1:

6 3
3 5
1 2
3 4
2 2
1 5
1 4
输出样例#1:

2

说明

Solution:

  今天PKU学长HRZ讲课,说到了本题,然后思路比较巧妙。

  方法就是对区间离散后,按原长度从小到大排序,然后用一个队列维护两个指针$l,r$,$O(n)$的去加入区间$s[l,r]+=1$,用线段树维护区间最大值,若区间最大值$\geq m$则从前往后把加入的区间删除,直到区间最大值刚好$< m$,那么用$l-1$所保存的长度和当前加入的区间长度差去更新答案,然后就没了。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int N=;
int n,m,maxn[N<<],add[N<<],ans=0x7fffffff;
int l=,r;
int *lst[N<<],cnt,tot;
struct node{
int l,r,len;
bool operator<(const node &a)const{return len<a.len;}
}a[N],Q[N]; il bool cmp(const int *a,const int *b) {return *a<*b;} il int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=;
while(x>=''&&x<='')a=(a<<)+(a<<)+x-,x=getchar();
return f?-a:a;
} il void pushup(int rt){maxn[rt]=max(maxn[rt<<],maxn[rt<<|]);} il void pushdown(int rt,int len){
if(add[rt]){
add[rt<<]+=add[rt],
add[rt<<|]+=add[rt];
maxn[rt<<]+=add[rt],
maxn[rt<<|]+=add[rt];
add[rt]=;
}
} il void update(int L,int R,int k,int l,int r,int rt){
pushdown(rt,r-l+);
if(L<=l&&R>=r){maxn[rt]+=k;add[rt]=k;return;}
int m=l+r>>;
if(L<=m) update(L,R,k,lson);
if(R>m) update(L,R,k,rson);
pushup(rt);
} int main(){
n=gi(),m=gi();
For(i,,n) a[i].l=gi(),a[i].r=gi(),a[i].len=a[i].r-a[i].l,lst[++cnt]=&a[i].l,lst[++cnt]=&a[i].r;
sort(lst+,lst+cnt+,cmp);
int k=-;
For(i,,cnt) {
if(*lst[i]!=k) k=*lst[i],*lst[i]=++tot;
else *lst[i]=tot;
}
sort(a+,a+n+);
For(i,,n) {
Q[++r].l=a[i].l,Q[r].r=a[i].r,Q[r].len=a[i].len;
update(a[i].l,a[i].r,,,tot,);
if(maxn[]>=m){
while(l<=r&&maxn[]>=m){
update(Q[l].l,Q[l].r,-,,tot,);
l++;
}
if(maxn[]<m) ans=min(a[i].len-Q[l-].len,ans);
}
}
cout<<(ans==0x7fffffff?-:ans);
return ;
}

P1712 [NOI2016]区间的更多相关文章

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

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

  2. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  3. 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化

    洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...

  4. 洛谷 P1712 [NOI2016]区间(线段树)

    传送门 考虑将所有的区间按长度排序 考虑怎么判断点被多少区间覆盖,这个可以离散化之后用一棵权值线段树来搞 然后维护两个指针$l,r$,当被覆盖次数最多的点的覆盖次数小于$m$时不断右移$r$,在覆盖次 ...

  5. 并不对劲的bzoj4651:loj2086:uoj222:p1712:[NOI2016]区间

    题目大意 有\(n\)(\(n\leq 5*10^5\))个闭区间\([L_1,R_1],[L_2,R_2],...,[L_n,R_n]\)(\(\forall i\in [1,n],0\leq L_ ...

  6. luogu P1712 [NOI2016]区间

    题目描述 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一 ...

  7. [洛谷P1712] NOI2016 区间

    问题描述 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一 ...

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

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

  9. luogu P1712 [NOI2016]区间 贪心 尺取法 线段树 二分

    LINK:区间 没想到尺取法. 先说暴力 可以发现答案一定可以转换到端点处 所以在每个端点从小到大扫描线段就能得到答案 复杂度\(n\cdot m\) 再说我的做法 想到了二分 可以进行二分答案 从左 ...

随机推荐

  1. mysql数据库和数据表的简单操作

    一.数据库的增删改查 1.新建数据库 CREATE DATABASE 数据库名 charset utf8; 数据库名规则:可以由字母.数字.下划线.@.#.$ 区分大小写, 不能使用关键字如 crea ...

  2. mysql 导出数据字典

    使用Navicat工具 查询: SELECT TABLE_SCHEMA AS '数据库', TABLE_NAME AS '表名', COLUMN_NAME AS '字段名', COLUMN_TYPE ...

  3. JS如何给ul下的所有li绑定点击事件,点击使其弹出下标和内容

    这是一个非常常见的面试题,出题方式多样,但考察点相同,下面我们来看看这几种方法:方法一: var itemli = document.getElementsByTagName("li&quo ...

  4. 五、RegExp(正则表达式)篇

    正则表达式,只用记住: 0./pattern/igm   i--不区分大小写 g--找到所有相匹配的 m--多行匹配  可以只写其中一个  ps:/pattern/i (无视大小写) 1." ...

  5. Nginx反向代理 Laravel获取真实IP地址(PHP)

    使用VUE前后端分离开发 后端使用Laravel  想要获取到用户的真实IP地址 因为分离开发不同源跨域问题 所以只能进行前端Nginx反向代理 location /api { rewrite ^/a ...

  6. Node.js 学习笔记 (一) 安装配置

    Node.js 安装配置 本安装教程以Node.js v4.4.3 LTS(长期支持版本)版本为例 Window 上安装Node.js 你可以采用以下两种方式来安装. 1.Windows 安装包(.m ...

  7. android 界面切换教程

    Android的界面切换其实并没有什么难度,就和java的界面切换一样简单,但是java的使用的是Swing框架进行的切换,而Android使用的是Intent 来切换框架的,这是一个全新的使用方法, ...

  8. BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 解题心得: 第一次接触莫队算法,很神奇,很巧妙.莫队算法主要就是用来解决多次询问时 ...

  9. Vue 去脚手架插件,自动加载vue文件,style怎么办

    书接上上会,因为当时也没想好怎么办,所以装聋作哑的忽略了Vue文件中的Style,Vue的做法我看着晕乎乎的,细想的话,无非就是自动填写到dom中,所担心的无非是命名冲突. 在一个项目中(像我这种自娱 ...

  10. 3155: Preprefix sum

    3155: Preprefix sum https://www.lydsy.com/JudgeOnline/problem.php?id=3155 分析: 区间修改,区间查询,线段树就好了. 然后,这 ...