写得很好的题解

一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除。然后事实也是这样做的……

具体起来:

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(区间离散化+线段树+决策单调尺取)的更多相关文章

  1. 离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers

    题目传送门 题意:给出一些花开花落的时间,问某个时间花开的有几朵 分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问.还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前 ...

  2. xdoj-1324 (区间离散化-线段树求区间最值)

    思想 : 1 优化:题意是覆盖点,将区间看成 (l,r)转化为( l-1,r) 覆盖区间 2 核心:dp[i]  覆盖从1到i区间的最小花费 dp[a[i].r]=min (dp[k])+a[i]s; ...

  3. [Noi2016]区间[离散化+线段树维护+决策单调性]

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 621  Solved: 329[Submit][Status][D ...

  4. POJ 2528 Mayor's posters 【区间离散化+线段树区间更新&&查询变形】

    任意门:http://poj.org/problem?id=2528 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  5. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

  6. 【BZOJ4653】【NOI2016】区间(线段树)

    [BZOJ4653][NOI2016]区间(线段树) 题面 BZOJ 题解 \(NOI\)良心送分题?? 既然是最大长度减去最小长度 莫名想到那道反复减边求最小生成树 从而求出最小的比值 所以这题的套 ...

  7. POJ 2528 - Mayor's posters - [离散化+区间修改线段树]

    题目链接:http://poj.org/problem?id=2528 Time Limit: 1000MS Memory Limit: 65536K Description The citizens ...

  8. 南阳理工 题目9:posters(离散化+线段树)

    posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 The citizens of Bytetown, AB, could not stand that ...

  9. hpu校赛--雪人的高度(离散化线段树)

    1721: 感恩节KK专场——雪人的高度 时间限制: 1 Sec  内存限制: 128 MB 提交: 81  解决: 35 [提交][状态][讨论版] 题目描述 大雪过后,KK决定在春秋大道的某些区间 ...

随机推荐

  1. iOS清理WebView的缓存

    NSHTTPCookie *cookie; NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; ...

  2. C++ 四种强制类型转变与区别之处

    使用标准C++的类型转换符:static_cast.dynamic_cast.reinterpret_cast和const_cast.1.static_cast    用法:static_cast&l ...

  3. xcode4中build Settings常见参数解析

    本文转载至 http://shiminghua234.blog.163.com/blog/static/263912422012411103526386/     1.Installation Dir ...

  4. JDK提供的几种常用的锁

    可重入互斥锁: Lock lock = new ReentrantLock() lock.lock(); ... lock.unlock(); 信号量: Semaphore semaphore = n ...

  5. ssh原理【转】

    1 转自 http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html 2 ssh远程登陆的原理 普通用户远程登陆 ssh jason@ho ...

  6. IOS中调用系统拨打电话发送短信

    一.调用打电话界面 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat ...

  7. Oracle:手工建库

    今天学习了小布老师的手工建库视频,自己也做了一遍,下面是创建过程记录: 本地环境oracle10.2.0.1 一.前期准备工作 1.设置环境变量 [oracle@app dbs]$ vi bbk.en ...

  8. 05:LGTB 与偶数

    总时间限制:  10000ms 单个测试点时间限制:  1000ms 内存限制:  65536kB 描述 LGTB 有一个长度为 N 的序列.当序列中存在相邻的两个数的和为偶数的话,LGTB 就能把它 ...

  9. 【前端】CentOS 7 系列教程之一: 安装 node 最新版

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_1.html 此系列教程从零开始,安装node.mysql.git,nginx.并且设置git自动部署. ...

  10. org.hibernate.hql.ast.QuerySyntaxException: Student is not mapped [from Student as stu where stu.sclass=?]

    java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException: t_aty_disease is not ...