CF1917C:Watering an Array 题解

C:

转化后题意:给出数列a,以及操作数列b,每次操作把 a 数列 [1,bi] 的每个树加一,问第几次操作后 ai=i 的位置最多。

作为 div2 的 C 题,数据中的 n 只给到了 2000,但其实这题 n 给到 1e6 都能做。

Solution:

原题中的 b 数列可以很长,但根据题意发现只需要截取前 2n 的长度就行,因为如果你不能在 2n 步之内将所有 ai 变成 i,我们就可以从一开始就采用 “12121212” 操作产生 n 次贡献。

将每个 ai 减去 i,我们想知道哪个时间 ai=0 的数量最多,然后发现 ai=0 是一个时间段,每个操作看做线段覆盖的话,ai=0 就是从 ai 条覆盖到 i 的线段到 ai+1 条覆盖到 i 的线段之间。

所以我们把脑袋转90度,把操作的序号看做一个个位置,从左到右扫描 a 数列,出现某操作线段的左端点时,在树状数组中操作的序号处加一,出现右端点就减去一,对于每个数二分 “出现 k 条线段的位置”。二分加树状数组是俩log,直接树状数组二分,一个log,常数还小。

然后就是a数列每个数字求出了对答案产生贡献的区间,可以差分记录区间加一,O(n)找出答案最大的时刻。

my submission


__EOF__

本文作者枫叶晴
本文链接https://www.cnblogs.com/maple276/p/18008768.html
关于博主:菜菜菜
版权声明:呃呃呃
声援博主:呐呐呐
posted @   maple276  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示