P8120 「RdOI R3.5」RMSQ 做法
题意
给定一个排列与一个序列,让你求出整个排列与序列中一个区间的最长公共子序列。
解法
首先我们延用 P1439 的方法,把序列的值改成这个值在排列中的下标,查询就变成了区间内最长上升一子序列,意思是每个值都是上一个值加一。
这时我们首先发现几乎做不到非根号,于是先考虑回滚莫队。
我们维护 \(end_i\) 表示以 \(i\) 这个值结尾的最长上升一子序列,再维护 \(st_i\) 表示以 \(i\) 这个值开头的最长上升一子序列,这两个在做加点的时候可以轻松维护。
如此在每次扩大区间时计算最大值并更新数组即可。
但是,这题有强制在线,不会让你如此轻易的做完。
于是,你考虑转回滚莫队为分块,做一些厉害的事情。
维护 \(f_{i,j}\) 表示从第 \(i\) 个块左端点开头,以 \(j\) 号点结尾的最长上升一子序列长度,\(g_{i,j}\) 表示从第 \(i\) 个块往前到 \(j\) 号点,以 \(j\) 号点开头的最长上升一子序列长度。
再随便维护一下 \(ans_{i,j}\) 表示 \(i\) 块到 \(j\) 块的最大值,此时可以计算左散块与整块,整块与整块,整块与右散块的答案了,于是就简易的做完了……吗?
发现一个最长上升一子序列可能会形如左散块的元素加整块的元素加右散块的元素,同时本题是这一部分拔高了难度。
但我们依旧可以做,询问时在左散块开一个桶 \(h_i\) 表示在左散块内以 \(i\) 结尾的最长上升一子序列,在处理右散块与整块时算一下左端点有可能的贡献就好了。

浙公网安备 33010602011771号