[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$,在覆盖次 ...
随机推荐
- 深入浅出Java concurrent
看 :http://www.blogjava.net/xylz/archive/2010/07/08/325587.html
- java日期操作常用工具
java日期操作常用工具 package com..util; import java.sql.Timestamp; import java.text.SimpleDateFormat; import ...
- 前端技术之_CSS详解第五天
前端技术之_CSS详解第五天 一.行高和字号 1.1 行高 CSS中,所有的行,都有行高.盒模型的padding,绝对不是直接作用在文字上的,而是作用在“行”上的. <!DOCTYPE html ...
- ffmpeg 的 tbr tbc 和 tbn的意义
tbn = the time base in AVStream that has come from the container tbc = the time base in AVCodecConte ...
- SublimeText3常用快捷键和优秀插件
SublimeText3常用快捷键和优秀插件 SublimeText是前端的一个神器,以其精简和可DIY而让广大fans疯狂.好吧不吹了直入正题 -_-!! 首先是安装,如果你有什么软件管家的话搜一下 ...
- Java并发-取消与关闭
如果外部代码可以再某个操作正常完成之前就将其置入"完成"状态,那么这个操作就是可以取消的.取消的原因有:用户请求取消.有时间限制的操作.应用程序事件.错误和关闭等 中断 如果使用某 ...
- Spring HTTP状态码枚举值对照表
使用Spring时总去查HTTP状态码对应的Spring枚举值的那篇代码,有点不方便,把代码拷贝出来统一替换格式做成了表格,放在这里,方便大家使用.(枚举类为HttpStatus) 枚举值 HTTP状 ...
- api大全
免费api大全(更新中) API大全 http://www.apidq.com/ (这个碉堡了) 天气接口 气象局接口 完整数据:http://m.weather.com.cn/data/10 ...
- python爬虫入门(九)Scrapy框架之数据库保存
豆瓣电影TOP 250爬取-->>>数据保存到MongoDB 豆瓣电影TOP 250网址 要求: 1.爬取豆瓣top 250电影名字.演员列表.评分和简介 2.设置随机UserAge ...
- java后台服务器实现极光推送
一.添加极光推送所需要的jar包,项目使用的maven,所以只需要在pom文件里添加jar包依赖 <dependency> <groupId>cn.jpush.api</ ...