[CP / Codeforces] “使用最小操作次数构造不下降序列类”题目

C. Squaring - 1800*
E. Look Back - 1700*


这两道题本质上是相同的(前者来自最近的 Div.2,后者来自两个月前的 Div. 3)。

E. Look Back [solution]

贪心策略可以很容易地想到——计算出每个元素的最小操作次数,累加可得最终答案。难点在于,我们不能直接将 “操作” 应用于元素上,否则可能会出现溢出,轻则 WA,重则 RE。

于是我们就会想,是否能在仅维护操作次数、不改变输入数组的值的前提下计算出最终答案呢?

这是完全可以的!不过,需要一点小小的数学推导:

记原数组为 a,操作次数数组为 opop[i] 表示原数组的第 i 个元素 a[i] 所需的最小操作次数,根据上面的分析得 ans=i=1nop[i]

假设我们现在已经通过某种方式计算出了 op[i] , 其中 1ik<n,现在想要计算 op[k+1]

根据题目要求,此时 a[k]op[k] 次操作下的值变为了 2op[k]a[k],注意我们并没有把这个值真的赋给 a[k],仅用于推导。那么,op[k+1] 就等于为了满足

2op[k]a[k]2op[k+1]a[k+1]

所可以取的最小值,注意这里 op[k],op[k+1] 均大于等于零

分类讨论。

如果 a[k]=a[k+1],显然 op[k+1]=op[k];
如果 a[k]>a[k+1],那么 op[k+1]=op[k]+t, tN
如果 a[k]<a[k+1],那么 op[k+1]=max(0,op[k]t), tN

可见,我们只需要找到 t 就行了。

a[k]>a[k+1] 为例,此时不等式变为:

a[k]2ta[k+1]

op 数组完全无关!假设原数组元素的最大值为 M,即便使用最简单的枚举法,找到这样的 t 也只需要花费 O(logM) 的时间,足够快了。

因此,我们可以使用上述算法计算出 op 数组,并得到最终答案,时间复杂度 O(nlogM),使用二分查找可以进一步优化到 O(nloglogM)

C. Squaring [solution]

(这道题的推导和上面大相径庭,请读者自行尝试。)

posted @   ZXPrism  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示