CF1648D题解

\(s_{i,j}\) 表示\(i\) 行前 \(j\)的价值和(即前缀和)。
之前模拟赛遇到过类似的线段覆盖问题,考虑 \(dp\),设 \(f_i\) 表示从 \((1,1)\) 走到 \((2,i)\) 且所选线段的右端点恰好覆盖到 \(i\) 的最大收益
将所有线段按右端点排序,然后对于 \(i\) 枚举以 \(i\) 为右端点的线段 \(x\) 进行转移。
转移有两种:

  • 从上一个线段的右端点走过来,即 \(\max\limits_{L_x-1\leq j\leq i-1} f_j+s_{2,i}-s_{2,j}\),可以用线段树维护。
  • 直接从 \((1,1)\) 走到 \((2,i)\),即 \(\max\limits_{L_x\leq j\leq i} s_{1,j}-s_{2,j-1}+s_{2,i}\),同样可以用线段树维护。

但上述 \(dp\) 存在问题,即线段覆盖的最右端点不一定是最后走到的最右端点,但是至多只有最后一个区间的右端点没有被走到。
image

枚举没有被走满的区间 \(x\),考虑上一个线段的右端点 \(i\)\(L_x-1\leq i\leq R_x-1\)),以及拐点 \(j\),为了方便,记 \(g_j=s_{3,n}-s_{3,j-1}+s_{2,j}\),于是就变成了询问区间 \([L_x-1,R_x] 中\) \(\max\limits_{i<j}f_i-s_{2,i}+g_j\)这个也可以用线段树维护,具体地,对于每个区间维护 \(ans\) 和区间 \(f,g\) 最大值,合并的时候取 左区间的 \(ans\),右区间的 \(ans\),左区间 \(f\)\(mx\) 和右区间 \(g\)\(mx\) 的和 三个值的最大值。

注意只用一条线段的情况特殊考虑,记 \(a_i=s_{1,i}-s_{2,i-1}\)\(b_i=s_{3,n}-s_{3,i-1}+s_{2,i}\),然后枚举用的区间,又变成询问 \(a_i+b_j\) 的最大值,处理方法同上。

posted on 2022-11-14 19:43  cool_tyl  阅读(36)  评论(1)    收藏  举报