CF1798E

题面

看到要求每一位的答案,首先考虑倒着扫,因为加数一般都比删数好做。

对于任意长为 m 的的序列 {b},我们都可以通过将 b1 改成 1,将 b2 改成 m2 使得 {b} 成为一个 multitest,因此操作数不会超过 2

现在讨论答案的三种情况:

  • 答案为 0{b} 已经是一个 multitest 了。
  • 答案为 1{b} 可以通过一次修改变成一个 multitest。
  • 答案为 2:排除了前两种之后的情况。

对于一个位置 i,它的后缀能构成一个 multitest 的充要条件是:i+1 的后缀能构成若干个 test,且 ai 的值等于 i+1 的后缀构成的 test 数。

fi 表示 i 的后缀能构成的 test 的个数,不难得出转移方程如下:

fi={1,i+ai=n0,i+ai>norfi+ai+1=0fi+ai+1+1,otherwise

{f} 可以 Θ(n) 求出。第 i 位答案为 0 的充要条件就是 fi+10ai=fi+1

如果答案不为 0,考虑两种情况:

  1. fi+10,但是 aifi+1
  2. fi+1=0

对于第一种情况,令 aifi+1 即可,操作数为 1

对于第二种情况,如果想要答案为 1,显然需要对 i+1 的后缀中的某一个数进行修改,使修改后 i+1 的后缀能构成 ai 个 test。

gi 表示在 i 的后缀中进行一次修改后,能得到的最多 test 数。

这个修改有两种情况:

  1. 修改 ai。这意味着我们可以随意改变第一个 test 的长度,也就是这第一个 test 可以接在后面的任意一个状态的前面,这种情况能得到的最大值为 maxj=i+1nfj+1
  2. 不修改 ai。因为 ai+1ai+ai 之间的数会被 ai 所在的 test 所包含,所以只有修改 i+ai+1 的后缀中的某个数才能有贡献。因此这种情况能得到的最大值为 maxj=i+ai+1ngj+1

后缀最大值可以边做边求,因此 {g} 也可以 Θ(n) 求出。那么“对 i+1 的后缀中的某一个数进行修改后,i+1 的后缀能构成 ai 个 test”的充要条件就是 gi+1ai

之所以这里是大于等于号,是因为如果能修改 ap 形成 x 个 test,那一定可以通过“让 ap 更大,覆盖掉下一个 test”或“让上一个 test 的第一个元素更大,覆盖掉 ap 所在的 test”,形成 x1 个 test。

剩下的情况答案就是 2 了。

时间复杂度显然 Θ(n)

赛时 AC 记录

posted @   untitled0  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示