[Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086
额...
首先,看到这道题,第一想法就是二分答案+线段树...
兴高采烈的认为我一定能AC,之后发现n是500000...
nlog^2=80%,亲测可过...
由于答案是求满足题意的最大长度-最小长度最小,那么我们可以考虑将区间按长度排序
之后,因为我们是需要最大最小,所以,我们必定选择在排完序的区间上取连续的一段是最优情况(起码不会比别的差)
因此,考虑双指针扫一下就可以了...
是不是很水?
由于懒得写离散化,一开始写的动态开点线段树,我*****什么鬼?mle?!256mb开不下!
loj+洛谷上95%,附上代码...
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
using namespace std;
#define N 500005
#define lson l,m,tr[rt].ls
#define rson m+1,r,tr[rt].rs
#define PushUp(rt) tr[rt].maxx=max(tr[tr[rt].ls].maxx,tr[tr[rt].rs].maxx)
struct no
{
int ls,rs,maxx,add;
}tr[N*40];
int n,m,ans,cnt;
struct node
{
int l,r,len;
}a[N];
bool cmp(const node &a,const node &b)
{
return a.len<b.len;
}
void PushDown(int rt)
{
if(tr[rt].add)
{
if(!tr[rt].ls)tr[rt].ls=++cnt;
if(!tr[rt].rs)tr[rt].rs=++cnt;
tr[tr[rt].ls].maxx+=tr[rt].add;
tr[tr[rt].rs].maxx+=tr[rt].add;
tr[tr[rt].ls].add+=tr[rt].add;
tr[tr[rt].rs].add+=tr[rt].add;
tr[rt].add=0;
}
}
void Update(int L,int R,bool c,int l,int r,int &rt)
{
if(!rt)rt=++cnt;
if(L<=l&&r<=R)
{
tr[rt].maxx+=c?1:-1;
tr[rt].add+=c?1:-1;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(m>=L)Update(L,R,c,lson);
if(m<R)Update(L,R,c,rson);
PushUp(rt);
}
int main()
{
ans=1<<30;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].len=a[i].r-a[i].l;
}
sort(a+1,a+n+1,cmp);
int l=1,r=0,rot=0;
while(r<n)
{
while(tr[rot].maxx<m&&r<n){r++;Update(a[r].l,a[r].r,1,0,1<<30,rot);}
if(tr[rot].maxx<m)break;
while(tr[rot].maxx>=m&&l<n){Update(a[l].l,a[l].r,0,0,1<<30,rot);l++;}
ans=min(a[r].len-a[l-1].len,ans);
}
printf("%d\n",ans==1<<30?-1:ans);
return 0;
}
这显然就不能AC,那么我们可以考虑用一下离散化...
离散化后,线段树的空间复杂度从(nlog(1<<30))变成(nlog(n*2))之后,空间就降下来了...
附上AC代码...
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
using namespace std;
#define N 500005
#define lson l,m,tr[rt].ls
#define rson m+1,r,tr[rt].rs
#define PushUp(rt) tr[rt].maxx=max(tr[tr[rt].ls].maxx,tr[tr[rt].rs].maxx)
struct no
{
int ls,rs,maxx,add;
}tr[N*10];
int p[N<<1];
int n,m,ans,cnt;
struct node
{
int l,r,len;
}a[N];
bool cmp(const node &a,const node &b)
{
return a.len<b.len;
}
void PushDown(int rt)
{
if(tr[rt].add)
{
if(!tr[rt].ls)tr[rt].ls=++cnt;
if(!tr[rt].rs)tr[rt].rs=++cnt;
tr[tr[rt].ls].maxx+=tr[rt].add;
tr[tr[rt].rs].maxx+=tr[rt].add;
tr[tr[rt].ls].add+=tr[rt].add;
tr[tr[rt].rs].add+=tr[rt].add;
tr[rt].add=0;
}
}
void Update(int L,int R,bool c,int l,int r,int &rt)
{
if(!rt)rt=++cnt;
if(L<=l&&r<=R)
{
tr[rt].maxx+=c?1:-1;
tr[rt].add+=c?1:-1;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(m>=L)Update(L,R,c,lson);
if(m<R)Update(L,R,c,rson);
PushUp(rt);
}
int main()
{
ans=1<<30;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
a[i].len=a[i].r-a[i].l;
p[(i<<1)-1]=a[i].l;
p[i<<1]=a[i].r;
}
sort(p+1,p+n*2+1);
for(int i=1;i<=n;i++)
{
int x=lower_bound(p+1,p+n*2+1,a[i].l)-p;
a[i].l=x;
x=lower_bound(p+1,p+n*2+1,a[i].r)-p;
a[i].r=x;
}
sort(a+1,a+n+1,cmp);
int l=1,r=0,rot=0;
while(r<n)
{
while(tr[rot].maxx<m&&r<n){r++;Update(a[r].l,a[r].r,1,1,n*2,rot);}
if(tr[rot].maxx<m)break;
while(tr[rot].maxx>=m&&l<n){Update(a[l].l,a[l].r,0,1,n*2,rot);l++;}
ans=min(a[r].len-a[l-1].len,ans);
}
printf("%d\n",ans==1<<30?-1:ans);
return 0;
}
离散化什么的,用lower_bound就好了,懒得写二分查找了...反正不会tle...
[Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086的更多相关文章
- 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化
洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...
- BZOJ5291/洛谷P4458/LOJ#2512 [Bjoi2018]链上二次求和 线段树
原文链接http://www.cnblogs.com/zhouzhendong/p/9031130.html 题目传送门 - LOJ#2512 题目传送门 - 洛谷P4458 题目传送门 - BZOJ ...
- 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)
题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...
- 洛谷P4459/loj#2511 [BJOI2018]双人猜数游戏(博弈论)
题面 传送门(loj) 传送门(洛谷) 题解 所以博弈论的本质就是爆搜么-- 题解 //minamoto #include<bits/stdc++.h> #define R registe ...
- 洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)
题面 传送门(loj) 传送门(洛谷) 题解 我果然是人傻常数大的典型啊-- 题解在这儿 //minamoto #include<bits/stdc++.h> #define R regi ...
- 洛谷P4457/loj#2513 [BJOI2018]治疗之雨(高斯消元+概率期望)
题面 传送门(loj) 传送门(洛谷) 题解 模拟赛的时候只想出了高斯消元然后死活不知道怎么继续--结果正解居然就是高斯消元卡常? 首先有个比较难受的地方是它一个回合可能不止扣一滴血--我们得算出\( ...
- BZOJ4653 & 洛谷1712 & UOJ222:[NOI2016]区间——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4653 https://www.luogu.org/problemnew/show/P1712 ht ...
- 【洛谷 P1712】 [NOI2016]区间 (线段树+尺取)
题目链接 emmm看起来好像无从下手, \(l_i,r_i\)这么大,肯定是要离散化的. 然后我们是选\(m\)个区间,我们先对这些区间按长度排个序也不影响. 排序后,设我们取的\(m\)个区间的编号 ...
- 洛谷 P1712 [NOI2016]区间(线段树)
传送门 考虑将所有的区间按长度排序 考虑怎么判断点被多少区间覆盖,这个可以离散化之后用一棵权值线段树来搞 然后维护两个指针$l,r$,当被覆盖次数最多的点的覆盖次数小于$m$时不断右移$r$,在覆盖次 ...
随机推荐
- 阅读spring源码
读Spring源码之前,你要先清楚,为什么你要用Spring... Spring最基本的功能是做为管理bean的容器,所以我以为应该先从org.springframework.context包了解咯, ...
- OOP的基本原则
OOP的基本原则 点击打开链接
- git push 报错 "Peer certificate cannot be authenticated with known CA certificates"
使用git push -u origin master 命令向远程仓库提交代码时报错:Peer certificate cannot be authenticated with known CA ce ...
- win7 64位专业版下的x64编译问题
在Django的开发过程中,碰到一个问题,就是所有本地库的位数必须是相同的,于是某些库需要重新编译一下,工作环境,不能用盗版程序,VC++ 2008\2010 Express版本身都不支持X64的编译 ...
- Web运营手记
1.图片是给活人用户看的,相对来讲,文字是给搜索引擎看的.精华内容争取要在网站或者频道主页里面让人看到. 2.搜索引擎喜欢看的几种文字:页面标题.关键词元信息(只有Bing管点用).描述(descri ...
- Django Channels简明实践
1.安装,如果你已经安装django1.9+,那就不要用官方文档的安装指令了,把-U去掉,直接用: sudo pip install channels 2.自定义的普通Channel的名称只能包含a- ...
- STOMP协议规范
原文: STOMP Protocol Specification, Version 1.2 摘要 STOMP是一个简单的可互操作的协议, 被用于通过中间服务器在客户端之间进行异步消息传递.它定义了一种 ...
- MySQL 的索引优化
索引类似大学图书馆建书目索引,可以提高数据检索的效率,降低数据库的IO成本.MySQL在300万条记录左右性能开始逐渐下降,虽然官方文档说500~800w记录,所以大数据量建立索引是非常有必要的.My ...
- [Java算法分析与设计]--单向链表(List)的实现和应用
单向链表与顺序表的区别在于单向链表的底层数据结构是节点块,而顺序表的底层数据结构是数组.节点块中除了保存该节点对应的数据之外,还保存这下一个节点的对象地址.这样整个结构就像一条链子,称之为" ...
- javascript 易漏点
javascript 是一种解释型语言,不是java或c++那样的编译语言.javascript指令以普通文本形式传递给浏览器,然后依次解释执行.它们不必首先“编译”成只有计算机处理器能理解的机器码. ...