LOJ #6564. 最长公共子序列

发布时间 2023-04-20 16:06:22作者: 275307894a

题面传送门

为啥大家都会这个科技?

首先我们有一个比较愚蠢的dp:设 \(f_{i,j}\) 表示第一个序列到第 \(i\) 位,第二个序列到第 \(j\) 位,最长公共子序列的长度。这样做是 \(O(n^2)\) 的。

如果你做过 dp 套 dp 你应该可以发现 \(f_{i,j}\) 行差分是只有 \(01\) 的,我们考虑用 bitset 来维护这个过程。

考虑一段极长的段 \([l,r]\) 满足 \([l,r)\) 全部都是 \(0\)\(r\)\(1\) ,那么考虑第一个串往后扩展一个位置的时候,如果这个段里面有能匹配的位置,那么 \(r\) 处的 \(1\) 就会到最前面的匹配的位置。

这个过程相当于对于原来的 \(f\) or 上能匹配的位置,然后对于每一段变成 lowbit。

对于单个段的 lowbit 怎么求?\(x\) xor \((x\) and \((x-1))\) 。那么怎么对多段同时减一呢?一个很好的性质就是每一段的开头前面一定是 \(1\) ,所以将 \(f\) 左移一位然后补上最开头的 \(1\) 即可。

发现你的 bitset 需要支持减法,手写即可。时间复杂度 \(O(\frac{nm}{\omega})\)

submission