【CF833E】Caramel Clouds

题面

洛谷

题目大意:

天上有\(n\)朵云,每朵云\(i\)会在时间\([li,ri]\)出现,你有\(C\)个糖果,你可以花费\(c_i\)个糖果让云\(i\)消失,同时需要保证你最多让两朵云消失.现在有\(m\)个独立的询问,每次给你一个需要让阳光照\(k\)时间的植

物,问你从时刻\(0\)开始,这个植物最快什么时候能长成.

\(n,m\leq 3e5\)

题解

这题好神仙啊。。。

我们首先记几个东西:

\(Free:\)表示当前空着的长度和

\(single[x]:\)表示只有\(x\)覆盖的长度

\(opt[x]:\)选出的两朵云中必定包含\(x\)的最大长度

\(Top:\)\(opt\)的最大值

\(cross[x][y]:\)表示只有\(x,y\)覆盖的长度

然后用一个\(set\)维护当前还未消失的云

分类讨论一下\(set\)中云的个数:

1、当\(set\)中没有云时,直接让\(Free\)加上贡献即可

2、当\(set\)中只有一朵云,更新\(single\)以及\(opt\)

3、当\(set\)中有两朵云,更新\(cross\)、\(opt\)

4、当\(set\)中云朵数大于二,不用管,因为此时一定不会比云朵数小于等于二的时候答案更优

至于更新的方法,看代码应该能看懂

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
void chkmax(int &x, int y) { if (x < y) x = y; }
const int MAX_N = 3e5 + 5;
struct Cloud { int l, r, c; } cld[MAX_N];
bool operator < (const Cloud &l, const Cloud &r) { return l.c < r.c; }
struct Query { int id, t; } q[MAX_N];
bool operator < (const Query &l, const Query &r) { return l.t < r.t; }
struct Node { int t, op, id; } a[MAX_N << 1]; int tot = 0;
bool operator < (const Node &l, const Node &r) { return l.t < r.t; }
int N, M, C, single[MAX_N], opt[MAX_N], ans[MAX_N];
map<int, int> cross[MAX_N];
set<int> s;
set<int>::iterator ite;
int Free, Top;
#define lson (o << 1)
#define rson (o << 1 | 1)
int mx[MAX_N << 2];
void modify(int o, int l, int r, int pos, int v) {
if (l == r) return (void)(mx[o] = v);
int mid = (l + r) >> 1;
if (pos <= mid) modify(lson, l, mid, pos, v);
else modify(rson, mid + 1, r, pos, v);
mx[o] = max(mx[lson], mx[rson]);
}
int find(int o, int l, int r) {
if (l == r) return l;
int mid = (l + r) >> 1;
if (mx[lson] > mx[rson]) return find(lson, l, mid);
else return find(rson, mid + 1, r);
}
int query(int o, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return find(o, l, r);
int mid = (l + r) >> 1, res = 0;
if (ql <= mid) res = query(lson, l, mid, ql, qr);
if (qr > mid) {
int tmp = query(rson, mid + 1, r, ql, qr);
if (single[tmp] > single[res]) res = tmp;
}
return res;
}
int sum(int x, int y) {
if (x > y) swap(x, y);
return single[x] + single[y] + cross[x][y];
}
void solve() {
int now = 0, pos = 1;
for (int i = 1; i <= tot; i++) {
int dlt = a[i].t - now; now = a[i].t;
if (!s.size()) Free += dlt;
else if (s.size() == 1) {
ite = s.upper_bound(0); int x = *ite;
single[x] += dlt; modify(1, 1, N, x, single[x]);
opt[x] += dlt;
int rem = C - cld[x].c;
if (rem >= 0) {
int val = single[x];
if (rem >= cld[1].c) {
int l = 1, r = N, res = 1;
while (l <= r) {
int mid = (l + r) >> 1;
if (cld[mid].c <= rem) res = mid, l = mid + 1;
else r = mid - 1;
}
int ql = 1, qr = res;
if (x == qr) --qr;
if (x < qr) { ql = x + 1; if (ql <= qr) chkmax(val, sum(x, query(1, 1, N, ql, qr))); ql = 1, qr = x - 1; }
if (ql <= qr) chkmax(val, sum(x, query(1, 1, N, ql, qr)));
}
chkmax(opt[x], val);
chkmax(Top, opt[x]);
}
} else if (s.size() == 2) {
ite = s.upper_bound(0); int x = *ite;
++ite; int y = *ite;
if (cross[x].count(y) > 0) cross[x][y] += dlt;
else cross[x][y] = dlt;
if (cld[x].c + cld[y].c <= C) {
chkmax(opt[x], sum(x, y)); chkmax(opt[y], sum(x, y));
chkmax(Top, opt[x]);
}
}
while (pos <= M && Top + Free >= q[pos].t) ans[q[pos].id] = now - (Top + Free - q[pos].t), ++pos;
if (pos > M) break;
if (a[i].op == 1) s.insert(a[i].id);
else s.erase(a[i].id);
}
}
int main () {
N = gi(), C = gi();
for (int i = 1; i <= N; i++) cld[i].l = gi(), cld[i].r = gi(), cld[i].c = gi();
sort(&cld[1], &cld[N + 1]);
for (int i = 1; i <= N; i++) {
a[++tot] = (Node){cld[i].l, 1, i};
a[++tot] = (Node){cld[i].r, -1, i};
}
sort(&a[1], &a[tot + 1]);
a[++tot] = (Node){(int)(2e9 + 7), 1, N + 1};
M = gi();
for (int i = 1; i <= M; i++) q[i].id = i, q[i].t = gi();
sort(&q[1], &q[M + 1]);
solve();
for (int i = 1; i <= M; i++) printf("%d\n", ans[i]);
return 0;
}

【CF833E】Caramel Clouds的更多相关文章

  1. 【CF833E】Caramel Clouds(线段树)

    [CF833E]Caramel Clouds(线段树) 题面 CF 洛谷 题解 首先把区间一段一段分出来,那么只有四种情况. 要么没有被任何一朵云被覆盖,那么直接就会产生这一段的贡献. 要么被一朵云覆 ...

  2. 【POJ3294】 Life Forms (后缀数组+二分)

    Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...

  3. 【转】查看 Linux 发行版名称和版本号的 8 种方法

    如果你加入了一家新公司,要为开发团队安装所需的软件并重启服务,这个时候首先要弄清楚它们运行在什么发行版以及哪个版本的系统上,你才能正确完成后续的工作.作为系统管理员,充分了解系统信息是首要的任务. 查 ...

  4. 【翻译】理解 LSTM 网络

    目录 理解 LSTM 网络 递归神经网络 长期依赖性问题 LSTM 网络 LSTM 的核心想法 逐步解析 LSTM 的流程 长短期记忆的变种 结论 鸣谢 本文翻译自 Christopher Olah ...

  5. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  6. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  7. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  8. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  9. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

随机推荐

  1. 匹配IP的正则表达式

    正则表达式匹配IP 1 ((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|[1-9])  

  2. hctf2016_302跳转绕csp---总结

    页面目录如下: register.php注册页面. user.php可发送消息给其他用户. profile.php可配置参数添加用户头像(加载eval js文件). static存在redirect. ...

  3. [转]从三层架构到MVC,MVP

    本来是不想跳出来充大头蒜的,但最近发现园子里关于MVC的文章和讨论之风越刮越烈,其中有些朋友的观点并不是我所欣赏和推荐的,同时最近也在忙着给公司里的同事做MVC方面的“扫盲工作”.所以就搜集了一些大家 ...

  4. PAT——1059. C语言竞赛

    C语言竞赛是浙江大学计算机学院主持的一个欢乐的竞赛.既然竞赛主旨是为了好玩,颁奖规则也就制定得很滑稽: 0. 冠军将赢得一份“神秘大奖”(比如很巨大的一本学生研究论文集……).1. 排名为素数的学生将 ...

  5. sharepoint 配置个人网站容量

    we have a SharePoint 2013 Standard edition implementation and 80 users. We are now starting to use M ...

  6. Vue指令 常见的几个内置指令

    1.v-if指令:判断指令,根据表达式值得真假来插入或删除相应的值. 2.v-show指令:条件渲染指令,无论返回的布尔值是true还是false,元素都会存在在html中,只是false的元素会隐藏 ...

  7. Page Object 设计模式-PO

    1.传统测试用例实现的弊端: 易读性差 复用性差 可维护性差 扩展性差 2.PO 设计模式图: 3.Page Object 的核心要素: 抽象封装一个 BasePage 基类,基类应该拥有一个只想 w ...

  8. Android 心跳呼吸动画

    废话少说,看东西 一个很简单的心跳呼吸的动画,几行代码搞定: 代码: private ImageView ivHart; //图片 AlphaAnimation alphaAnimation = nu ...

  9. JS知识点整理(二)

    前言 这是对平时的一些读书笔记和理解进行整理的第二部分,第一部分请前往:JS知识点整理(一).本文包含一些易混淆.遗漏的知识点,也会配上一些例子,也许不是很完整,也许还会有点杂,但也许会有你需要的,后 ...

  10. #leetcode刷题之路22-括号生成

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为:[ "((()))", "(()())&q ...