可能更好的阅读体验
upd: 2023.11.9 突然想到想来修缮一下题解。
upd: 2024.10.16 感谢 @Mirasycle 指出了错误,官方题解已经更正。
什么时候给的黑,感觉应该不至于?
DP 优化部分感谢 @rsjw 的 slope trick 思路。
solution
首先不考虑对 ai 取 max,显然直接按照 k 降序排序最优。
接下来考虑 ai 的限制,如果取到了 ai 一定放在最后面最优。
为了方便设 fi,j 为前 i 个,j 个数字不取 max,最后答案和 ∑b 的差的最小值。
设 limi=bi−ai
fi,j={fi−1,j+limij=0min{fi−1,j+limi,fi−1,j−1+ki×j}j>0
这样时间复杂度为 Θ(n2)。
考虑优化。
首先对于样例输出一个整个 f。
我们通过观察样例发现对于给定的 i,在 j 改变的时候是下凸的。
对 j 一维差分,设 gi,j=fi,j−fi,j−1(j>0)。
我们可以发现 gi 到 gi+1 的变化似乎很有规律,可以试着直接用数据结构来优化这个转移(slope trick)。
我们利用 fi,j 的转移把 gi,j 的转移算出来
默认 1<j<i,将 fi,j=fi,0+j∑k=1gi,k 带入 fi,j 的递推式。
得到
fi,0+j∑k=1gi,k=min{fi−1,0+j∑k=1gi−1,k+limi,fi−1,0+j−1∑k=1gi−1,k+ki×j}
化简得
limi+j∑k=1gi,k=j−1∑k=1gi−1,k+min{gi−1,j+limi,ki×j}
对于上式用 j−1 代替 j
limi+j−1∑k=1gi,k=j−2∑k=1gi−1,k+min{gi−1,j−1+limi,ki×(j−1)}
两式相减,得到
gi,j=gi−1,j−1+min{gi−1,j+limi,ki×j}−min{gi−1,j−1+limi,ki×(j−1)}
由于 k 单调不增,对 i 归纳可以发现,对自变量 j,gi−1,j 的增长速度不会比 ki×j 慢。所以随着 j 的增大,存在一个分界点,使得 min{gi−1,j+limi,ki×j} 前一段的取到 gi−1,j,后一段取到 limi,ki×j。
因此,从 gi 到 gi+1,分别是三段转移:第一段不变,第二段为新增加的一个数字,第三段区间加一个数。
最后答案为最大前缀和。
用平衡树维护这个变化过程,O(nlogn)。
https://codeforces.com/contest/1787/submission/191206679
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具