【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)
题目链接
emmm看起来好像无从下手,
\(l_i,r_i\)这么大,肯定是要离散化的。
然后我们是选\(m\)个区间,我们先对这些区间按长度排个序也不影响。
排序后,设我们取的\(m\)个区间的编号是\(b_1,b_2,...,b_m\),
若\(b_m\)确定,我们肯定是要尽量使\(b_1,b_2,...,b_{m-1}\)尽量接近\(b_m\)的,这样可使代价最小。
所以,就可以尺取了。
定义两个指针\(l,r\),首先\(r\)指针不停右移覆盖一遍扫到的区间直到满足条件有一个点被连续覆盖\(m\)次,怎么判断?显然维护一棵最大值线段树就好了。
当满足条件,就让\(l\)指针右移直到不满足条件,更新答案。
#include <cstdio>
#include <algorithm>
using std::sort;
#define INF 2147483647
const int MAXN = 650010;
int n, m, q;
char ch;
inline int max(int a, int b){
return a > b ? a : b;
}
inline int min(int a, int b){
return a > b ? b : a;
}
inline int read(){
q = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9') { q = q * 10 + ch - '0'; ch = getchar(); }
return q;
}
struct Seg{
int l, r, len;
bool operator < (const Seg A) const{
return len < A.len;
}
}s[MAXN];
struct LSH{
int id, pos, val;
bool operator < (const LSH A) const{
return val < A.val;
}
}p[MAXN << 1];
int cnt, num;
namespace SegTree{
#define left (now << 1)
#define right (now << 1 | 1)
int Max[MAXN << 2 << 1], lazy[MAXN << 2 << 1];
inline void pushup(int now){
Max[now] = max(Max[left], Max[right]);
}
inline void pushdown(int now){
if(lazy[now]){
Max[left] += lazy[now];
Max[right] += lazy[now];
lazy[left] += lazy[now];
lazy[right] += lazy[now];
lazy[now] = 0;
}
}
void update(int now, int l, int r, int wl, int wr, int p){
if(l >= wl && r <= wr){ Max[now] += p; lazy[now] += p; return; }
pushdown(now);
int mid = (l + r) >> 1;
if(wl <= mid) update(left, l, mid, wl, min(mid, wr), p);
if(wr > mid) update(right, mid + 1, r, max(mid + 1, wl), wr, p);
pushup(now);
}
int query(int now, int l, int r, int wl, int wr){
if(l >= wl && r <= wr) return Max[now];
int ans = 0;
pushdown(now);
int mid = (l + r) >> 1;
if(wl <= mid) ans = max(ans, query(left, l, mid, wl, min(mid, wr)));
if(wr > mid) ans = max(ans, query(right, mid + 1, r, max(mid + 1, wl), wr));
return ans;
}
}using namespace SegTree;
int ans = INF;
int main(){
n = read(); m = read();
for(int i = 1; i <= n; ++i){
s[i].l = read(); s[i].r = read();
s[i].len = s[i].r - s[i].l;
p[++cnt].val = s[i].l; p[cnt].id = i; p[cnt].pos = 1;
p[++cnt].val = s[i].r; p[cnt].id = i; p[cnt].pos = 2;
} p[0].val = -1;
sort(p + 1, p + cnt + 1);
for(int i = 1; i <= cnt; ++i)
if(p[i].pos == 1)
if(p[i].val != p[i - 1].val)
s[p[i].id].l = ++num;
else s[p[i].id].l = num;
else
if(p[i].val != p[i - 1].val)
s[p[i].id].r = ++num;
else s[p[i].id].r = num;
sort(s + 1, s + n + 1);
int l = 1, r = 0;
while(r < n){
while(r < n && Max[1] < m){
++r;
update(1, 1, num, s[r].l, s[r].r, 1);
}
if(Max[1] < m) break;
int tmp;
while(Max[1] >= m) tmp = s[l].len, update(1, 1, num, s[l].l, s[l].r, -1), ++l;
ans = min(ans, s[r].len - tmp);
}
printf("%d\n", ans == INF ? -1 : ans);
return 0;
}
【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)的更多相关文章
- 洛谷$P1712\ [NOI2016]$区间 线段树
正解:线段树 解题报告: 传送门$QwQ$ $umm$很久以前做的了来补个题解$QwQ$ 考虑给每个区间按权值($r-l$从大往小排序,依次加入,然后考虑如果有一个位置被覆盖次数等于$m$了就可以把权 ...
- 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化
洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...
- Luogu P1712 [NOI2016]区间(线段树)
P1712 [NOI2016]区间 题意 题目描述 在数轴上有 \(N\) 个闭区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\) .现在要从中选出 \(M\) 个区间, ...
- 洛谷 P1712 [NOI2016]区间(线段树)
传送门 考虑将所有的区间按长度排序 考虑怎么判断点被多少区间覆盖,这个可以离散化之后用一棵权值线段树来搞 然后维护两个指针$l,r$,当被覆盖次数最多的点的覆盖次数小于$m$时不断右移$r$,在覆盖次 ...
- [洛谷P1712] NOI2016 区间
问题描述 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x,使得对于每一 ...
- 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)
洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...
- [NOI2016]区间 线段树
[NOI2016]区间 LG传送门 考虑到这题的代价是最长边减最短边,可以先把边按长度排个序,双指针维护一个尺取的过程,如果存在包含某个点的区间数\(\ge m\),就更新答案并把左指针右移,这样做的 ...
- 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)
Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
随机推荐
- node 发送 post 请求 get请求。
因为我们部门打算用node请求restful 然后慢慢替换掉服务端,以后直接请求soa的接口,让前端的数据更贴切项目,因为我们服务端接口和app公用一套,由于业务的需求和版本不统一(例如app6.4的 ...
- 如何理解Java中参数传递只能传值?
以前学习C#的时候,是完全在工作岗位上学习,一些底层较为深入的道理都不是很清楚.如今学习了Java,对于Java参数传递只能传值,不能传引用(指针)感到很困惑,在C#中不是常常说把某个引用传递到函数中 ...
- 位运算 & 网络序字节序
一.初识位运算 位运算,见词明意,二进制运算,通常需要将运算数转换为二进制再进行处理,如果是在程序语言中则无需自己进行进制转换,基本的位操作符有如下几种:与(&).或(|).异或(^).取反( ...
- 「暑期训练」「Brute Force」 Far Relative’s Problem (CFR343D2B)
题意 之后补 分析 我哭了,强行增加自己的思考复杂度...明明一道尬写的题- -(往区间贪心方向想了 其实完全没必要,注意到只有366天,直接穷举判断即可. 代码 #include <bits/ ...
- 《机器学习实战》 in python3.x
机器学习实战这本书是在python2.x的环境下写的,而python3.x中好多函数和2.x中的名称或使用方法都不一样了,因此对原书中的内容需要校正,下面简单的记录一下学习过程中fix的部分 1.pr ...
- MATLAB中矢量场图的绘制 (quiver/quiver3/dfield/pplane) Plot the vector field with MATLAB
1.quiver函数 一般用于绘制二维矢量场图,函数调用方法如下: quiver(x,y,u,v) 该函数展示了点(x,y)对应的的矢量(u,v).其中,x的长度要求等于u.v的列数,y的长度要求等于 ...
- ipfs02
IPFS-day02 其他常用操作 添加文件并用文件夹包裹 ipfs add xxx -w 把內容快取到本地,并提供给他人.官网文档 ipfs pin add QmT7TX5vGmFz86V8cDkP ...
- term "JavaScript"
在Web浏览器上下文中理解的总称“JavaScript”包含几个非常不同的元素. 其中一个是核心语言(ECMAScript),另一个是Web API的集合,包括DOM(文档对象模型) JavaScri ...
- 【iOS开发】UIView之userInteractionEnabled属性介绍
http://my.oschina.net/hmj/blog/108002 属性作用 该属性值为布尔类型,如属性本身的名称所释,该属性决定UIView是否接受并响应用户的交互. 当值设置为NO后,UI ...
- EasyUI 显示表单数据 小记
界面图: