【题解】CF1621G Weighted Increasing Subsequences

常规,但不常规。

思路来自 @gyh.

思路

BIT 优化计数。

本来考虑的是对 LIS 进行计数,得到一个对 [] 形式的值套三层求和的方式,然后再瞪眼找优化方法,但是没有发现什么好的处理方法,于是只能考虑转换计数方法。

考虑通过每个位置对答案的贡献计数。假设某个位置 x 被一个合法的子序列 i1,ik 包含,考虑此时需要满足的限制。

其实很简单,考虑最后一个满足题目限制的位置,令 y 为最靠后的满足 ay>ax 的位置。只需限制 ik<y,就可以通过位置 y 满足题目的限制。同时容易发现 y 以及之后的位置都不可能满足限制,所以这个条件是充要的。

对于每个位置,考虑在统计以其为开头的上升子序列时计算它对答案的贡献。换言之,对于 1xn,统计 [x,y1] 中包含 x 的上升子序列的个数。

通过树状数组优化朴素的 dp 做法,可以达到 O(n2logn) 的复杂度。

同时可以观察得到合法的 y 一定是原序列的后缀最大值,可以进一步减小常数。

优化发现没法再转化统计方式,于是考虑通过容斥一类的方式做一些手脚。先假定所有包含 x 的上升子序列均符合限制,再容斥减去不符合限制的子序列。

分类讨论。当子序列以 [x,y1] 中的位置结尾时,序列一定符合条件;当子序列以 y 结尾时,不符合题目限制;当子序列以 [y+1,n] 中的位置结尾时,因为 y 的定义,一定不可能从中找出比 ay 大的值,所以这种情况矛盾,不可能统计。

这意味着我们只需要先预处理出以 x 为开头的上升子序列数量,再计算以 x 开头且 y 为结尾的上升子序列数量。

同时题目有进一步的性质:令 z 为满足 z>yaz 最大的位置。对于某个 y,其对应的所有 x 都应当满足 azax<ay,也就是对于每个 y,其对应的 ax 一定在某个区间内,统计的时候只需要考虑这些位置,直接通过定义二分预处理出来。

又因为 xy 可以看成是一种单射关系,也就是每个 x 所在的被 y 确定的区间是唯一的,所以均摊的复杂度是 O(nlogn).

两次转化算是比较常规,就是瞪不出来题目的性质,跟做初中几何一个样。

代码

posted @   kymru  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示
主题色彩