\(\mathscr{Description}\)

  Link.

  有 \(n\) 个人站在数轴上,第从左往右第 \(i\) 个人的坐标是 \(x_i\),每个人手上有一支烟花棒,每支烟花棒能燃烧 \(T\) 秒,燃尽后无法再点燃。初始时只有 \(k\) 手上的烟花棒是点燃的,求这些人的移动速度上限的最小值 \(v\in\mathbb N\),使得能够用这支烟花棒薪火相传,点燃所有烟花棒。

  \(n\le10^5\)。

\(\mathscr{Solution}\)

  跪拜出题人系列。

  显然二分答案,考虑如何检查当前答案 \(v\) 的合法性。

  先得到一些有基础性意义的贪心转化:

  1. 任意时刻,只需要一支燃烧的烟花棒存在。

  2. 所有人会向燃着的烟花棒移动。

  3. 当一支剩余燃烧时间为 \(t\) 的烟花棒点燃另一支烟花棒,等价于另一支烟花棒获得 \(T+t\) 的燃烧时间,这支烟花棒立即燃尽。(转化到原问题情景:两个人一起跑,要燃尽时再传火。)

  想像从 \(k\) 出发点燃烟花棒的情景,对于某个时刻,已经点燃过的烟花棒一定是一个区间 \([l,r]\),且 \(k\in[l,r]\)。根据性质 1,此时 \([l,r]\) 之外的人的相对位置是不变的,我们可以想象作区间 \([l,r]\) 被缩成了一个点。

  进一步,在这个条件下,“时刻”这一概念已经不重要了——无论何时,把 \(x_i\) 和 \(x_{i+1}\),缩在一起所需的时间都是 \(\frac{x_{i+1}-x_i}{2v}\)。而根据性质 3.,把这两个坐标缩起来,对烟花棒剩余燃烧时间的影响也恒为 \(\Delta t_i=-\frac{x_{i+1}-x_i}{2v}\)。记 \(P=\langle \Delta t_{k-1},T,\Delta t_{k-2},T,\cdots,\Delta t_1,T\rangle\),\(Q=\langle \Delta t_k,T,\Delta t_{k+1},T,\cdots,\Delta t_{n-1},T\rangle\),问题转化为:初始时有剩余时间 \(t=T\),每次从序列 \(P\) 或者 \(Q\) 的开头取出一个 \(\Delta t\),令 \(t\leftarrow t+\Delta t\),在保证 \(t\ge 0\) 的情况下将 \(P\) 和 \(Q\) 删空。

  尝试贪心?唯一显然的结论是若 \(P\) 的开头或者 \(Q\) 的开头不小于 \(0\),我们可以放心大胆取出来,而都小于 \(0\) 的情况就很难讨论清楚了。当然,每次“涉险”取走负数后,我们又会立马把露出来的非负数全部取走。我们能否规避“都小于 \(0\)”的讨论,用已知结论描述完整的贪心过程?

  接下来这步,或说是构造,说起来平淡:我们“如果”能把 \(P\) 和 \(Q\) 从开头起,分为若干极短的段,每段描述为二元组 \((t_0,\Delta t)\),满足 \(\Delta t\ge0\),表示为了消除这一段,初始时至少有 \(t_0\) 的剩余燃烧时间,消除后获得 \(\Delta t\) 的燃烧时间。由于划分的极短性,每次必然消除完整的一段而不会半途而废,不然稳亏不赚。

  这种“虚妄”有什么用?如果“如果”不成立,不还是干瞪眼?

  等等,如果“如果”不成立,例如 \(P\) 的“如果”不成立,那么就存在 \(P\) 的一段极长后缀 \(P'\),满足 \(P'\) 任意前缀和为负数。我们引入《TENET》的宇宙观,如果有一个逆熵的人从结束状态开始贪心,他的初始时间 \(t\)——也就是我们的结束时间 \(t\),是确定的;他每次必须从 \(P\) 的末尾取数,当然 \(P\) 中的数也取反,那么……

  极长后缀 \(P'\),取相反数再翻转得到 \(P''\),满足 \(P''\) 任意后缀和为正数……那么 \(P''\) 就不存在任意前缀和为负数的后缀……再者,\(P''\) 可以被划分为上文中的若干极短段,也就是说,这个逆熵的人完全可以在“如果”的美好愿景下做贪心,直到把 \(P'\) 消掉!

  然后呢然后呢?顺熵的人把 \(P\) 消除剩下一个 \(P'\),逆熵的人把 \(P'\) 反着消除,两个人相遇,我们作为顺熵的人,灵机一动,逆着逆熵的人的行动构造方案,不就把 \(P\) 消除了吗?

  神谕啊!

  实现上,可以把 \(\Delta t_i\) 转化到势差 \(h_{i+1}-h_i\) 上,所用东西乘上 \(2v\),构造 \(x_i\) 的势 \(h_i=2vTi-x_i\),顺带把初始的 \(t=T\) 一块儿囊括;在消去区间 \([l,r]\) 时保持 \(h_r\ge h_l\) 即可。算法复杂度是 \(\mathcal O(n\log V)\) 的,其中 \(V\) 是一堆乱七八糟东西的值域上限。


  从神谕中体会到什么?

  ——如果末状态已知,那它何不可做初状态?

  ——用时间的流向逆转“死局”,让它成为“必胜”条件。(好魔怔。

  出题人 nb。

\(\mathscr{Code}\)

/*+Rainybunny+*/

#include <bits/stdc++.h>

#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i) typedef long long LL; const int MAXN = 1e5;
int n, st, T, x[MAXN + 5];
LL hgt[MAXN + 5]; inline bool check(const int v) {
rep (i, 1, n) hgt[i] = 2ll * v * T * i - x[i];
if (hgt[1] > hgt[n]) return false;
int tarL = st, tarR = st;
per (i, st - 1, 1) if (hgt[i] <= hgt[tarL]) tarL = i;
rep (i, st + 1, n) if (hgt[i] >= hgt[tarR]) tarR = i;
int l = st, r = st;
while (tarL < l || r < tarR) {
int pl = l, pr = r;
for (int i = pl - 1; i >= tarL && hgt[i] <= hgt[pr]; --i) {
if (hgt[i] <= hgt[pl]) pl = i;
}
for (int i = pr + 1; i <= tarR && hgt[i] >= hgt[pl]; ++i) {
if (hgt[i] >= hgt[pr]) pr = i;
}
if (pl == l && pr == r) return false;
l = pl, r = pr;
} l = 1, r = n;
while (l < tarL || tarR < r) {
int pl = l, pr = r;
for (int i = pl + 1; i <= tarL && hgt[i] <= hgt[pr]; ++i) {
if (hgt[i] <= hgt[pl]) pl = i;
}
for (int i = pr - 1; i >= tarR && hgt[i] >= hgt[pl]; --i) {
if (hgt[i] >= hgt[pr]) pr = i;
}
if (pl == l && pr == r) return false;
l = pl, r = pr;
}
return true;
} int main() {
scanf("%d %d %d", &n, &st, &T);
rep (i, 1, n) scanf("%d", &x[i]); int l = 0, r = 1e9;
while (l < r) {
int mid = l + r >> 1;
// printf("%d?\n", mid);
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", l);
return 0;
}

Solution -「JOISC 2017」「LOJ #2392」烟花棒的更多相关文章

  1. loj 2392「JOISC 2017 Day 1」烟花棒

    loj 答案显然满足二分性,先二分一个速度\(v\) 然后显然所有没有点火的都会往中间点火的人方向走,并且如果两个人相遇不会马上点火,要等到火快熄灭的时候才点火,所以这两个人之后应该在一起行动.另外有 ...

  2. loj#2391 「JOISC 2017 Day 1」港口设施

    分析 https://yhx-12243.github.io/OI-transit/records/uoj356%3Bloj2391%3Bac2534.html 代码 #include<bits ...

  3. 「JOISC 2017 Day 3」幽深府邸

    题解: 和hnoi2018day2t1基本一样 我想了半小时想出了一个很麻烦的做法 写了之后发现假掉了 刚开始想的是 先预处理出每个门要打开至少要在左边的哪个点$L[]$,右边的哪个点$R[]$ 对每 ...

  4. JOISC 2017

    Day1 「JOISC 2017 Day 1」开荒者 首先观察部分分发现分档很多,于是考虑一步步思考上来. 首先有一点关键观察(一): 风吹的顺序是无所谓的,令分别往东.西.南.北吹了 \(r, l, ...

  5. LOJ 2288「THUWC 2017」大葱的神力

    LOJ 2288「THUWC 2017」大葱的神力 Link Solution 比较水的提交答案题了吧 第一个点爆搜 第二个点爆搜+剪枝,我的剪枝就是先算出 \(mx[i]\) 表示选取第 \(i \ ...

  6. Loj #2731 「JOISC 2016 Day 1」棋盘游戏

    Loj 2731 「JOISC 2016 Day 1」棋盘游戏 JOI 君有一个棋盘,棋盘上有 \(N\) 行 \(3\) 列 的格子.JOI 君有若干棋子,并想用它们来玩一个游戏.初始状态棋盘上至少 ...

  7. [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞

    [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...

  8. 【LOJ】#3036. 「JOISC 2019 Day3」指定城市

    LOJ#3036. 「JOISC 2019 Day3」指定城市 一个点的可以dp出来 两个点也可以dp出来 后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可 #include < ...

  9. 【LOJ】#3034. 「JOISC 2019 Day2」两道料理

    LOJ#3034. 「JOISC 2019 Day2」两道料理 找出最大的\(y_{i}\)使得\(sumA_{i} + sumB_{y_i} \leq S_{i}\) 和最大的\(x_{j}\)使得 ...

  10. 【LOJ】#3032. 「JOISC 2019 Day1」馕

    LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...

随机推荐

  1. Web开发核心

    文章目录 1.http协议简介 2.http协议特性 3.http请求和响应协议 4.最简单的Web程序 5.基于flask搭建web⽹站 6.浏览器开发者⼯具(重点) 1.http协议简介 HTTP ...

  2. FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频

    ​ijkplayer是Bilibili公司(简称B站)基于FFmpeg3.4研发并开源的国产播放器,它可运行于Android和iOS系统,既支持播放本地视频文件,也支持播放网络上的流媒体链接. 之前的 ...

  3. Chrome 130 版本新特性& Chrome 130 版本发行说明

    Chrome 130 版本新特性& Chrome 130 版本发行说明 一.Chrome 130 版本浏览器更新 1. 新的桌面提示 Chrome 130 引入了一种新的 Toast 样式,用 ...

  4. CF1503E 2-Coloring

    CF1503E 2-Coloring cjx 组合强. 思路 观察一下题目,不难发现只有当黄色形成如下的单峰时才合法. (染错色了,将就一下) 其中两座峰的峰顶高度相加等于 \(m\),为了方便统计, ...

  5. OSPF协议

    OSPF(Open Shortest Path First)开放式最短路径优先,是一种链路状态型路由协议,用于在网络中计算最短路径.OSPF协议是基于Dijkstra算法的,使用链路状态信息来计算最短 ...

  6. VAE变分自编码器Keras实现

    变分自编码器(variational autoencoder, VAE)是一种生成模型,训练模型分为编码器和解码器两部分. 编码器将输入样本映射为某个低维分布,这个低维分布通常是不同维度之间相互独立的 ...

  7. 【FAQ】Harmo【FAQ】HarmonyOS SDK 闭源开放能力 — 公共模块

    1.问题描述: 文档哪里能找到所有的权限查看该权限是用户级的还是系统级的. 解决方案: 您好,可以看一下下方链接是否可以解决问题: https://developer.huawei.com/consu ...

  8. 深入JUnit源码之Runner

    初次用文字的方式记录读源码的过程,不知道怎么写,感觉有点贴代码的嫌疑.不过中间还是加入了一些自己的理解和心得,希望以后能够慢慢的改进,感兴趣的童鞋凑合着看吧,感觉JUnit这个框架还是值得看的,里面有 ...

  9. 简单理解Linux File的操作

    类Unix系统是支持多个进程打开同一个文件,进行读写. 得益于类Unix系统对于文件操作的特殊设计. 分为三个数据结构 进程表项:其中包含进程中打开的文件和设备的文件描述符.还包含该文件描述符对应的文 ...

  10. C#中使用IMemoryCache实现内存缓存

    1 缓存基础知识 缓存是实际工作中非常常用的一种提高性能的方法. 缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能和可伸缩性. 缓存最适用于不经常更改的数据. 通过缓存,可以比从原始数据源返 ...