20250722 总结
A. LIS
考虑每个点如何产生贡献(对于多个区间的总和且与节点有关的问题,我们可以思考,每个点如何产生贡献):
-
当它作为一个可以被转移的点时
-
当它作为数列开头时
第二个很好处理,我们看第一个如何做,考虑到题目描述中讲到是第一个最小的(题目描述如下)
对于 \(i < j \le R\),选取最小的 \(j\),满足 \(a_j > a_i\)
不可能存在跳过一个比当前节点大或相等的点去处理前面的点,所以一个点只能被最后一个大于等于自己的点之后的所有点转移,我们考虑单调栈处理问题,从后往前扫描,如果当前点大于等于栈中点,说明栈中点的答案在当前点之后,记录下栈中点的答案即可,最后要清空栈,我们认为是一个巨大的点作为栈中点答案。
考虑结尾,包括当前节点的子序列末尾在当前节点后,不管后面有没有,有 \(n - i + 1\) 个结尾会因它产生贡献,将贡献和多少个结尾相乘就是它能产生的贡献就可以了。
B. 碰瓷
一眼 DP,当 T 可以拼出 S 时,T 必然是 S 的子序列。
看到 T 的长度不过 100,考虑 nm 的时间复杂度。
由于不可以在开头加数,所以 T 的开头必然与 S 的开头重合,我们视作枚举开头点要求与 T 的相同。
由于不能加与上一个相同的数,如果 S 的相同字母前缀比 T 的要长,那么如果要拼出要拼很多与 T 首字母相同的字母,所以不可行,有一个例外,如果 S 前缀包含了 T,它是存在一个贡献的
对于开头以后的字母,由于不是开头,与开头之间必然有一个不同的字母间隔,或者本身就与开头不同,必然可以想办法插进去。
将这些问题判完后,我们只需要判断子序列可以了,在子序列后面拼的数,子序列结尾到 \(n\) 的数的数量就是方案,拼法同上。
C. 旋律
对于一个长度为 \(d\) 的旋律,它在字符串长度为 \(d\) 的时候产生,当它不是旋律时,必然是因为出现了一个异类,如果要消除这个异类,必然会使长度增长,所以长度为 \(d\) 的旋律满足单调性,它在长度为 \(d\) 的时候产生,在一个可以二分出来的位置消失。
我们将整个过程离线下来,枚举旋律长度,然后二分找终结位置即可。
二分如何判断?分两种情况:
ababa
长度为 4
我们发现,只要末尾的 'a' 和首项的 'a' 相同即可,这样子我们可以复制一份 'bab' 到末尾,形成旋律
abaaba
长度为 3
这个可以直接将前 3 个和后 3 个对比
对于
abaaaba
长度为 3
我们发现这个没有旋律,那么必然在过去存在一个位置使得这种情况被判掉了
总结:如果长度较长为从头数 \(d\) 个和倒数 \(d\) 个,较短为从头数 \(n - d\) 个和倒数 \(n - d\) 个,我们发现其实是一样的
D. 非负
我们可以反过来考虑,我们对于一个区间需要删除一些 -1,那么假设不用删,就是一个子段问题,我们考虑什么情况下会要删 -1,当最大子段和跑到一个马上小于 0 的位置时,我们需要将下一个 -1 删除,这样就可以将当前最大子段和和下一个最大子段和连起来,达到更大的最大子段和,这样肯定是优的。
但是还有一个条件,前面我们默认为前缀,但是后缀也需要保证,当前缀超过了总和,接下来将会是一段 -1 将超过的掰回来了,最终回到总和,那么这样的后缀将会是负的,由于选 1 肯定是最优的,所以我们可以选择将总和抬上去,删掉一些 -1 使得总和等于最大子段和。
最大子段和问题直接看 P4513 小白逛公园
那么如何将总和抬上去?用最大子段和减去总和,就是要删去的 -1 数量,有一个问题,我们思考到要将最大子段和中间的 -1 删去,但是并没有任何操作处理了这个问题,由于删去 -1 可以将最大子段和向上抬,所以间接的就体现在最大子段和减总和上面。
总和在实际操作中不需要随着删 -1 的变化而变化,因为总和是用来计算删去多少个 -1 的数值。

浙公网安备 33010602011771号