BZOJ4653(区间离散化+线段树+决策单调尺取)
一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除。然后事实也是这样做的……
具体起来:
1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按长度排序的话),那么只要发现当前选取的这些从左到右的区间可以得到m及以上就可以了,没必要特地考虑具体选哪些,然后ans = min(ans, 右len - 左len)即可。
2.判断这些区间是否可行的方法是:出现一个区间就把区间内所有点+1,线段树维护最大值,所以segment[1].maxx >= m时该区间可行,然后1e9太大,把每个区间端点离散化一下。
3.复杂度太大,优化手法是发现如果当前的左端区间和右端区间都合法的话,因为我们是按照长度排序的,所以右端区间没理由往右移了,只会让答案更差。所以枚举左端即可,右端类似尺取的方法即可。然后就是常见手法,遇到一个新的r就插进树里+1,路过一个l就从树里-1。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <sstream>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <fstream>
#include <bitset>
#define init(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define irep(i, a, b) for (int i = a; i >= b; i--)
#define ls(p) (p) << 1
#define rs(p) (p) << 1 | 1
using namespace std; typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int inf = 0x3f3f3f3f;
const ll INF = 1e18; template <typename T> void read(T &x) {
x = ;
int s = , c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-') s = -;
for (; isdigit(c); c = getchar())
x = x * + c - ;
x *= s;
} template <typename T> void write(T x) {
if (x < ) x = -x, putchar('-');
if (x > ) write(x / );
putchar(x % + '');
} template <typename T> void writeln(T x) {
write(x);
puts("");
} const int maxn = 1e6 + ; int n, m, c[maxn], tot, ans = inf;
struct Section {
int l, r, len; bool operator < (const Section y) const {
return len < y.len;
}
}a[maxn]; struct Node {
int l, r, maxx, tag;
}t[maxn << ]; void build(int l, int r, int p) {
t[p].l = l, t[p].r = r;
if (l == r) {
t[p].maxx = t[p].tag = ;
return;
}
int mid = (l + r) >> ;
build(l, mid, ls(p));
build(mid + , r, rs(p));
} void Push_down(int p) {
if (t[p].tag) {
t[ls(p)].maxx += t[p].tag;
t[rs(p)].maxx += t[p].tag;
t[ls(p)].tag += t[p].tag;
t[rs(p)].tag += t[p].tag;
t[p].tag = ;
}
} void Update(int l, int r, int p, int k) {
if (l <= t[p].l && t[p].r <= r) {
t[p].maxx += k;
t[p].tag += k;
return;
}
Push_down(p);
int mid = (t[p].l + t[p].r) >> ;
if (l <= mid) Update(l, r, ls(p), k);
if (mid < r) Update(l, r, rs(p), k);
t[p].maxx = max(t[ls(p)].maxx, t[rs(p)].maxx);
} int main() {
read(n), read(m);
rep(i, , n) {
read(a[i].l);
read(a[i].r);
a[i].len = a[i].r - a[i].l;
c[++tot] = a[i].l;
c[++tot] = a[i].r;
}
//离散化
sort(c + , c + + tot);
tot = unique(c + , c + + tot) - c - ;
rep(i, , n) {
a[i].l = lower_bound(c + , c + + tot, a[i].l) - c;
a[i].r = lower_bound(c + , c + + tot, a[i].r) - c;
}
sort(a + , a + + n);
//线段树维护
build(, tot, );
for (int l = , r = ; l <= n; l++) {
while (t[].maxx < m && r < n) {
++r;
Update(a[r].l, a[r].r, , );
}
if (t[].maxx == m) {
ans = min(ans, a[r].len - a[l].len);
} else break;
Update(a[l].l, a[l].r, , -);
} if (ans == inf) puts("-1");
else writeln(ans);
return ;
}
BZOJ4653(区间离散化+线段树+决策单调尺取)的更多相关文章
- 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers
题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...
- xdoj-1324 (区间离散化-线段树求区间最值)
思想 : 1 优化:题意是覆盖点,将区间看成 (l,r)转化为( l-1,r) 覆盖区间 2 核心:dp[i] 覆盖从1到i区间的最小花费 dp[a[i].r]=min (dp[k])+a[i]s; ...
- [Noi2016]区间[离散化+线段树维护+决策单调性]
4653: [Noi2016]区间 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 621 Solved: 329[Submit][Status][D ...
- POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】
任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Total S ...
- BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针
BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...
- 【BZOJ4653】【NOI2016】区间(线段树)
[BZOJ4653][NOI2016]区间(线段树) 题面 BZOJ 题解 \(NOI\)良心送分题?? 既然是最大长度减去最小长度 莫名想到那道反复减边求最小生成树 从而求出最小的比值 所以这题的套 ...
- POJ 2528 - Mayor's posters - [离散化+区间修改线段树]
题目链接:http://poj.org/problem?id=2528 Time Limit: 1000MS Memory Limit: 65536K Description The citizens ...
- 南阳理工 题目9:posters(离散化+线段树)
posters 时间限制:1000 ms | 内存限制:65535 KB 难度:6 描述 The citizens of Bytetown, AB, could not stand that ...
- hpu校赛--雪人的高度(离散化线段树)
1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec 内存限制: 128 MB 提交: 81 解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...
随机推荐
- python day- 16 面向对象
1.类的相关知识 类:是指具有相同属性和技能的一类事物. 比如:人类 ,植物类,动物类,狗类. 对象:是类中的某一个实例,是类的具体表现. 比如:具体到某个人,某一个植物,某一条狗. class 是p ...
- CodeChef - COUNTARI FTT+分块
Arithmetic Progressions Given N integers A1, A2, …. AN, Dexter wants to know how many ways he can ch ...
- SWT.Shell
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SWT_Shell ...
- 请问snmp到底是干啥的。
这个事情分两方面来说:首先是路由器这部分.路由器开启SNMP功能之后,它能够对自己的每个接口上的流量有一个统计,当然统计的不单单只有流量.然后路由器把统计到的内容按一定的格式保存起来.这个格式是大家都 ...
- 根据用户时区显示当地时间 javascript+php
在跨时区应用中会用到下面代码,这是以前写的一段代码. 服务器保存相关时间配置,保存形式为GMT时间,客户端需要根据客户所在时区做相应显示,以符合客户习惯. 1. [代码][JavaScript]代码 ...
- jstl标签: c:Foreach详解
为循环控制,它可以将集合(Collection)中的成员循序浏览一遍.运作方式为当条件符合时,就会持续重复执行的本体内容. 为循环控制,它可以将集合(Collection)中的成员循序浏览一遍.运作方 ...
- OpenCV——PS滤镜算法之 Ellipsoid (凹陷)
// define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...
- servlet的<url-pattern>
① 完全匹配 <url-pattern>/test/list.do</url-pattern> ② 路径匹配 <url-pattern>/*</url-pat ...
- Linux Cache 机制
在阅读文章前,您应该具备基本的存储器层次结构知识,至少要了解局部性原理.要详细了解cache基本原理,可以参考本书<深入理解计算机系统>中存储器体系结构一章: 带着疑问来看文章,cache ...
- 【转】Darwin Streaming Server 核心代码分析
无意中看到了dqzhangp的一篇博客,分析了DSS的核心架构,读完顿时感觉豁然开朗,茅塞顿开,写得非常的鞭辟入里,言简意赅,我想没有相当的功力是写不出这样的文章的,情不自禁转到自己空间来,生怕弄丢了 ...