CF1557

Codeforces Round #737 (Div. 2)

D. Ezzat and Grid

题意

给出一个 n109n\cdot 10^9 的网格,初始网格上的数字都是0,再给出 mm 个横向区间该区间上的数字都是1
每个横向区间用 i,l,ri, l, r 表示,第 ii 行上列号为 [l,r][l,r] 上的数字都是1,如 1,3,41, 3, 4 表示第1行上 [3,4][3,4] 列上都是1

现在可以删去一些行,使得剩下的行中的任意相邻两行至少有一列都是1

求最少的删去行数,并输出删去的行号

思路

最一开始想到了dp但没有往下像,因为感觉空间复杂度炸了,结果是可以优化一维的

f(i,j)f(i, j) 表示前 ii 行中最大的剩余行数,且剩余的最后一行的第 jj 列为1

那么对于当前第 ii 行有转移:

f(i,j)={1+maxkCif(i1,k),grid(i,j)=1;f(i1,j),grid(i,j)=0.f(i,j) = \begin{cases} 1+\max\limits_{k\in C_i} f(i-1,k), &grid(i, j) = 1;\\ f(i-1,j), &grid(i, j)=0. \end{cases}\\

其中 CiC_i 为第 ii 行中为1的列号

通过上面的转移方程可以发现,dp的第一维是可以去掉的,可以通过线段树优化第二维转移时间复杂度为 O(logM)O(logM) (需要先离散一下)

然后就是求解最后要删除的行号,因为删除的行号等价于求解最后保留的行号,对于第 ii 行,一定可以在线段树上找到最大的 valval 对应的顶点,将每个顶点再存储一个行号,代表上次最大值更新是通过该行更新过来的,那么当前的第 ii 行的上一行就是最大 valval 顶点对应的行号,存储下来,最后最大保留的行号就能形成一条链,通过线段树根顶点的行号,倒序求出链上的结点就是最大可以保留的行号

总时间复杂度 O(NlogM)O(NlogM)


CF1557
https://wty-yy.github.io/posts/18657/
作者
wty
发布于
2021年8月10日
许可协议