最长公共子序列
最长公共子序列
给四个长度为 $n$ 的序列 $ \{a_i\},\{b_i\},\{c_i\},\{d_i\}$。求这四个序列最长公共子序列的长度。
子序列为原序列删去若干位置后剩下的序列,可以不用连续,例如$ \{1,2\},\{1,3\}$ 均为 $ \{1,2,3\}$。
数据范围
对于所有数据:$ 1 \le n \le 10000,1 \le a_i,b_i,c_i,d_i \le n $,$\{a_i\},\{b_i\},\{c_i\} $ 任何数字出现次数都 $ \le 2$ 次。
Subtask 1(30%) : $ n \le 50$
Subtask 2(40%) : $\{a_i\},\{b_i\},\{c_i\},\{d_i\}$ 为1 到n排列。
Subtask 3(30%) : 无特殊性质。
Sol
考虑dp,f[i][0/1][0/1][0/1]表示d中匹配到第i位,abc中匹配的是前一个还是后一个的最长公共子序列。
效率64*n*n,T了
我们发现当abcd四维都小于时才可以转移。
那我们们就四维偏序cdq维护。
具体实现:把a,b,,c,d,排序,记录一下id,然后先分治一个mid,处l-mid的贡献。
然后让l~mid的a改成0,mid+1~r的a改成1,同时按b为第一关键字,id为第二关键字排序。
然后进第二层cdq,在这一层先分治l~mid,mid+1~r,使得左右的c都有序。
然后把本层的c归并排序,同时记录一个点的是左边还是右边。
如果一个点是左边且A为0,则可以贡献,是右边且a为1,可以收到贡献。
等价于a<a且b<b