BZOJ.4653.[NOI2016]区间(线段树)
考虑二分。那么我们可以按区间长度从小到大枚举每个区间,对每个区间可以得到一个可用区间长度范围。
我们要求是否存在一个点被这些区间覆盖至少\(m\)次。这可以用线段树区间加、求max维护(或者在线段树上二分)。
但这是两个\(\log\)的。
我们不二分,按长度枚举每个区间。这样边枚举边判一下是否有点被覆盖\(m\)次就好了。
复杂度\(O(n\log n)\)。
动态开点值域线段树MLE 95分啊QAQ。。(必然了)
另外动态开点的区间修改,下传标记的时候要先判有没有儿子(没有要新建节点)。
因为这个浪费2h还算值吧。。
//42136kb 8316ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=5e5+5;
int ref[N<<1];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Interval
{
int l,r,len;
Interval() {}
Interval(int l,int r):l(l),r(r) {len=r-l;}
bool operator <(const Interval &x)const
{
return len<x.len;
}
}A[N];
struct Segment_Tree
{
#define S N<<3
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,l,m
#define rson rs,m+1,r
int tot,mx[S],tag[S];
#undef S
#define Update(x) mx[x]=std::max(mx[ls],mx[rs])
#define Upd(x,v) tag[x]+=v,mx[x]+=v
inline void PushDown(int rt)
{
Upd(ls,tag[rt]), Upd(rs,tag[rt]), tag[rt]=0;
}
void Modify(int rt,int l,int r,int L,int R,int val)
{
if(L<=l && r<=R) {Upd(rt,val); return;}
if(tag[rt]) PushDown(rt);
int m=l+r>>1;
if(L<=m) Modify(lson,L,R,val);
if(m<R) Modify(rson,L,R,val);
Update(rt);
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline int Find(int x,int r)
{
int l=1,mid;
while(l<r)
if(ref[mid=l+r>>1]<x) l=mid+1;
else r=mid;
return l;
}
int main()
{
#define S 1,1,cnt
int n=read(),m=read(),t=0;
for(int i=1; i<=n; ++i) ref[++t]=read(),A[i]=Interval(ref[t-1],ref[++t]=read());
std::sort(A+1,A+1+n);
std::sort(ref+1,ref+1+t); int cnt=1;
for(int i=2; i<=t; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
for(int i=1; i<=n; ++i) A[i].l=Find(A[i].l,cnt), A[i].r=Find(A[i].r,cnt);
int ans=2e9;
for(int l=1,r=1; r<=n; ++r)
{
while(T.mx[1]<m && r<=n) T.Modify(S,A[r].l,A[r].r,1), ++r;
--r;
if(T.mx[1]>=m)
{
while(T.mx[1]>=m) T.Modify(S,A[l].l,A[l].r,-1), ++l;
ans=std::min(ans,A[r].len-A[l-1].len);
}
else break;
}
printf("%d\n",ans==2e9?-1:ans);
return 0;
}
动态开点:
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=5e5+5;
char IN[MAXIN],*SS=IN,*TT=IN;
struct Interval
{
int l,r,len;
Interval() {}
Interval(int l,int r):l(l),r(r) {len=r-l;}
bool operator <(const Interval &x)const
{
return len<x.len;
}
}A[N];
struct Segment_Tree
{
#define S N*32
#define ls son[x][0]
#define rs son[x][1]
#define lson ls,l,m
#define rson rs,m+1,r
int tot,son[S][2],mx[S],tag[S];
#undef S
#define Update(x) mx[x]=std::max(mx[ls],mx[rs])
#define Upd(x,v) tag[x]+=v,mx[x]+=v
inline void PushDown(int x)
{
if(!ls) ls=++tot; Upd(ls,tag[x]);
if(!rs) rs=++tot; Upd(rs,tag[x]);
tag[x]=0;
}
void Modify(int &x,int l,int r,int L,int R,int val)
{
if(!x) x=++tot;
if(L<=l && r<=R) {mx[x]+=val,tag[x]+=val; return;}
if(tag[x]) PushDown(x);
int m=l+r>>1;
if(L<=m) Modify(lson,L,R,val);
if(m<R) Modify(rson,L,R,val);
Update(x);
}
}T;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int main()
{
#define S root,0,1000000000
int n=read(),m=read(),root=0;
for(int i=1,tmp; i<=n; ++i) tmp=read(),A[i]=Interval(tmp,read());
std::sort(A+1,A+1+n);
int ans=2e9;
for(int l=1,r=1; r<=n; ++r)
{
while(T.mx[root]<m && r<=n) T.Modify(S,A[r].l,A[r].r,1), ++r;
--r;
if(T.mx[root]>=m)
{
while(T.mx[root]>=m) T.Modify(S,A[l].l,A[l].r,-1), ++l;
ans=std::min(ans,A[r].len-A[l-1].len);
}
else break;
}
printf("%d\n",ans==2e9?-1:ans);
return 0;
}
BZOJ.4653.[NOI2016]区间(线段树)的更多相关文章
- BZOJ4653 [NOI2016]区间 [线段树,离散化]
题目传送门 区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就 ...
- [NOI2016]区间 线段树
[NOI2016]区间 LG传送门 考虑到这题的代价是最长边减最短边,可以先把边按长度排个序,双指针维护一个尺取的过程,如果存在包含某个点的区间数\(\ge m\),就更新答案并把左指针右移,这样做的 ...
- Luogu P1712 [NOI2016]区间(线段树)
P1712 [NOI2016]区间 题意 题目描述 在数轴上有 \(N\) 个闭区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\) .现在要从中选出 \(M\) 个区间, ...
- UOJ222 NOI2016 区间 线段树+FIFO队列
首先将区间按长度排序后离散化端点(这里的“长度”指的是离散化之前区间的实际长度) 然后模拟一个队列,区间按排好的顺序依次进入,直到某个点被覆盖了M次.之后依次出队,直到所有点都被覆盖小于M次 修改和询 ...
- bzoj 4653: [Noi2016]区间
Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置.换句话说,就是使得存在一个 x ...
- BZOJ4653: [Noi2016]区间(线段树 双指针)
题意 题目链接 Sol 按照dls的说法,一般这一类的题有两种思路,一种是枚举一个点\(M\),然后check它能否成为答案.但是对于此题来说好像不好搞 另一种思路是枚举最小的区间长度是多少,这样我们 ...
- 洛谷$P1712\ [NOI2016]$区间 线段树
正解:线段树 解题报告: 传送门$QwQ$ $umm$很久以前做的了来补个题解$QwQ$ 考虑给每个区间按权值($r-l$从大往小排序,依次加入,然后考虑如果有一个位置被覆盖次数等于$m$了就可以把权 ...
- BZOJ 4653 [Noi2016]区间(Two pointers+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4653 [题目大意] 在数轴上有n个闭区间 [l1,r1],[l2,r2],...,[l ...
- BZOJ 4653: [Noi2016]区间 双指针 + 线段树
只要一堆线段有重叠次数大于等于 $m$ 次的位置,那么一定有解 因为重叠 $m$ 次只需 $m$ 个线断,将那些多余的线断排除掉即可 先将区间按照长度从小到大排序,再用 $two-pointer$ 从 ...
随机推荐
- STM32F103X datasheet学习笔记---Interrupts and events
1.前言 本章主要介绍STM32中断和事件相关的内容 2.NVIC NVIC管理着包括内核异常等中断 主要特性 68个外部中断源(不包含16个内部中断线) 可编程优先级为16级 低延迟异常和中断处理 ...
- linux新内核的freeze框架以及意义【转】
转自:https://blog.csdn.net/dog250/article/details/5303442 linux的电源管理发展非常迅速,比如在挂起到内存的时候,系统会冻结住所有的进程,也就是 ...
- 字符驱动之二操作方法(struct file_operations)【转】
转自:http://blog.chinaunix.net/uid-26837113-id-3157515.html 从上一篇我们看到了字符驱动的三个重要结构,那我现在跟大家详细的说说 struct f ...
- KVM -> 虚拟机在线热添加技术_04
热添加技术 1.KVM在线热添加硬盘
- zabbix3.0.4-agent通过shell脚本获取mysql数据库登陆用户
zabbix3.0.4获取数据库登陆用户趋势详解 主要思路: 通过zabbix客户端shell脚本mysql命令取出用户表中的数据将结果反馈给zabbix,画出趋势图 1.修改zabbix-agent ...
- aliyun服务器ecs被ddos后无法被zabbix-server监控的处理
ecs绑定的域名被ddos攻击后,阿里云黑洞ecs服务器一个月,此时zabbix服务端无法联系到zabbix-agent会一直报错 解决办法: 1.在ecs前添加slb并把之前指向ecs的域名a.ch ...
- 02-第一个JavaScript代码
在页面中,我们可以在body标签中放入<script type=”text/javascript”></script>标签对儿,<script type=”text/ja ...
- C++ code:位操作实例(bit operation example)
某任务需要在A.B.C.D.E这五个人中物色人员去完成,但派人受限于下列条件: (1)若A去,则B跟去 (2)D,E两人中必有人去 (3)B,C两人中必有人去,但只去一人 (4)C,D两人要么都去,要 ...
- wpf 自定义属性的默认值
public int MaxSelectCount { get { return (int)GetValue(MaxSelectCountProperty); } set { SetValue(Max ...
- poj2352树状数组解决偏序问题
树状数组解决这种偏序问题是很厉害的! /* 输入按照y递增,对于第i颗星星,它的level就是之前出现过的星星中,横坐标小于i的总数 */ #include<iostream> #incl ...