Longest Common Subsequence

题意

求出长度为 nn 的数组 AA 和长度为 mm 的数组 BB 的最长不下降公共子序列的长度。

满足 1≤n,m≤106,1≤Ai,Bi≤31\le n,m\le 10^6,1\le A_i,B_i\le 3。

思路

因为 1≤Ai,Bi≤31\le A_i,B_i\le 3,所以答案应该时这个形式的 1,1,⋯ ,2,2,⋯3,31,1,\cdots,2,2,\cdots 3,3。

考虑先先枚举 11 和 33 的个数再计算 22 的个数,假设他们分别有 i,ji,j 个。

定义数组 sumAi=∑i=1n[Ai=2]sumA_i=\sum\limits_{i=1}^n [A_i=2],lAilA_i 为从左向右第 ii 个 11 的位置,rBirB_i 表示从右向左第 ii 个 33 的位置,对于 BB 数组也同理。

因为其中 11 和 33 的区间不能重合(保证单调递增),所以需要满足 lAi<rBj,lBi<rBjlA_i<rB_j,lB_i<rB_j。因为计算的时公共子序列,所以除去连个序列都拥有的 11 和 33 剩余的 22 的数量应该取最小值。根据 sumsum 的定义与前缀和的思想,有贡献的 22 的数量为 min⁡(sumArAj−1−sumAlAi,sumBrBj−1−sumBlBi)\min(sumA_{rA_j-1}-sumA_{lA_i},sumB_{rB_j-1}-sumB_{lB_i}) 。

因为随 ii 增加 jj 的最大值会减小具有单调性,所以可以使用双指针来维护 lAi<rBj,lBi<rBjlA_i<rB_j,lB_i<rB_j。

因为我们维护的时公共子序列,所以只有在满足 sumArAj−1−sumAlAi≤sumBrBj−1−sumBlBisumA_{rA_j-1}-sumA_{lA_i}\le sumB_{rB_{j-1}}-sumB_{lB_i} 的情况下我们才可以取 bb 数组中间的贡献。

再进行移项得到 sumArAj−1−sumBrBj−1≤sumAlAi−sumBlBisumA_{rA_j-1}-sumB_{rB_{j-1}}\le sumA_{lA_i}-sumB_{lB_i} 就可以使用树状数组维护了。

code