BZOJ4653

UOJ222

考虑二分。那么我们可以按区间长度从小到大枚举每个区间,对每个区间可以得到一个可用区间长度范围。

我们要求是否存在一个点被这些区间覆盖至少\(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]区间(线段树)的更多相关文章

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

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

  2. [NOI2016]区间 线段树

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

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

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

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

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

  5. bzoj 4653: [Noi2016]区间

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

  6. BZOJ4653: [Noi2016]区间(线段树 双指针)

    题意 题目链接 Sol 按照dls的说法,一般这一类的题有两种思路,一种是枚举一个点\(M\),然后check它能否成为答案.但是对于此题来说好像不好搞 另一种思路是枚举最小的区间长度是多少,这样我们 ...

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

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

  8. BZOJ 4653 [Noi2016]区间(Two pointers+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4653 [题目大意] 在数轴上有n个闭区间 [l1,r1],[l2,r2],...,[l ...

  9. BZOJ 4653: [Noi2016]区间 双指针 + 线段树

    只要一堆线段有重叠次数大于等于 $m$ 次的位置,那么一定有解 因为重叠 $m$ 次只需 $m$ 个线断,将那些多余的线断排除掉即可 先将区间按照长度从小到大排序,再用 $two-pointer$ 从 ...

随机推荐

  1. sublime3添加python编译系统

    好记性不如烂笔头 为sublime3添加python编译系统,这里使用的anonconda2中的python.exe(即python2.7版本) 步骤: (1)打开sublime,打开“工具-> ...

  2. SVM较全面介绍,干货!(转载)

    很不错的一篇介绍SVM的文章,证明通俗易懂! 转自:https://blog.csdn.net/v_july_v/article/details/7624837 前言 动笔写这个支持向量机(suppo ...

  3. SCons: 替代 make 和 makefile 及 javac 的极好用的c、c++、java 构建工具

    http://scons.org/ https://www.ibm.com/developerworks/cn/linux/l-cn-scons/index.html 后附:另外,WAF是一个基于sc ...

  4. win32编程:L,_T() ,TEXT和_TEXT

    L的使用: 在字符串前面的大写字母L,用来告诉编译器该字符串应该作为Unicode来编译.它用来将ASNI转换为Unicode,Unicode字符串中每个字符占16位(两个字节),而在ASNI中每个字 ...

  5. freerradius 错误:pap: WARNING: No "known good" password found for the user

    具体错误如下: 1) # Executing section authorize from file /usr/local/etc/raddb/sites-enabled/default(1)   a ...

  6. 内核中 subsys_initcall 以及初始化标号

    今天在看内核中无线的实现时,发现一个调用 subsys_initcall(cfg80211_init);搜索一些资料: subsys_initcall 的定义在 include/linux/init. ...

  7. centos6.5环境disconf管理端安装配置详解

    操作系统:centos6.5 x86_64 安装目录/data 1.安装nginx1.10.1 rpm -ivh http://nginx.org/packages/centos/6/noarch/R ...

  8. 集成Struts2+Spring+Hibernate_两种方案

    集成Struts2+Spring+Hibernate 第一种方案:让Spring创建Struts2的Action,不让Spring完全管理Struts2的Action      Struts2 Act ...

  9. dell R720服务器设置开机启动顺序

    开机按F2进入系统启动设置,也可以按F11进入快速启动配置

  10. apache服务器的常用功能及设置

    安装httpd yum -y install  httpd     服务脚本:/etc/rc.d/init.d/httpd        脚本配置文件:/etc/sysconfig/httpd     ...