CF2043C Sums on Segments

注意到,要求一个值域是 {1,1} 的序列的子段和有多少种不同的取值,实际上就是求它的最小子段和 a 到最大子段和 b 之间有多少个整数。因为可以证明,每个处于 [a,b]Z 中的数,都至少有一个子段与之对应——要得到和为 b1 的子段,只需要从最大子段的一端删去一个和为 1 的子段即可(一定可以做到),进而可以一步一步得到 b2,b3,1,0;相似的,从最小子段和可以一步一步得到 a+1,a+2,1,0

有了上述结论,我们可以对特殊值 x 左右两边的只含 1,1 的段 dp 求最大子段和 max、最小子段和 min,把 [min,max]Z 中的数全部加入 set。对于含 x 的区间,可以求出左段的最大后缀和 max1 和最小后缀和 min1,以及右段的 max2,min2,取值范围就是 [min1+min2+x,max1+max2+x]Z,同样加入 set。遍历的值域不超过 n,复杂度 O(nlogn);也可以用线段树优化到 O(logn)AC代码

posted @   XYukari  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示