CF1557D.Ezzat and Grid(2200分线段树)

Posted 绿憨憨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1557D.Ezzat and Grid(2200分线段树)相关的知识,希望对你有一定的参考价值。

https://codeforces.com/contest/1557

题意:

给出一个\\(n*10^9\\)的01矩阵。用\\(m\\)个区间表示。(\\(1 \\leq n,m \\leq 3 \\times 10^5\\)

每个区间包含三个信息:\\(i,l,r\\)。表示在第\\(i\\)行,第\\(l\\)个元素到第\\(r\\)个元素是1。

一个矩阵被称为美丽的,当且仅当,这个矩阵任意相邻的两行,存在一个位置\\(p\\)使得这两行这个位置都为1。

询问最少要删除几行使得矩阵是美丽的。

输出一个方案。

题解:

我们定义:

\\(f[i]\\)为在保留第\\(i\\)行的前提下,最少删除几行使得前\\(i\\)行是美丽的。

\\(pre[i]\\)\\(f[i]\\)表示的状态下,上一个未被删除的行的编号。

那么我们可以枚举\\(i\\)之前的行,设我们当前枚举的是\\(j\\),如果第\\(i\\)行和第\\(j\\)行有某个位置都是1,那么\\(f[i]\\)可以由\\(f[j]+i-j-1\\)转移过来。

换句话说,对于所有满足条件的\\(j\\),我们取\\(f[j]+i-j-1\\)的最小值作为\\(f[i]\\)的答案。

即:\\(f[i]=min_{j=1}^{i-1}f[j]+i-j-1[行i和行j有一个位置都是1]\\)

然后把这个式子移项,想方设法让\\(i\\)\\(j\\)独立:

\\(f[i]-i=min_{j=1}^{i-1}f[j]-j-1\\)

观察到式子右边只和\\(j\\)有关了。

然后我们考虑如何找满足条件\\([行i和行j有一个位置都是1]\\)\\(j\\)的数量。

可以先对所有区间\\([i,l,r]\\)做离散化处理,然后用线段树维护两个信息:

下标\\(i\\)表示第\\(i\\)个点为\\(1\\)的所有行的最小\\(f[j]-j-1\\)值和对应\\(j\\)的值。

节点\\(u\\)表示所管辖区间内\\(f[j]-j-1\\)的最小值和对应\\(j\\)的值。

然后在转移的过程中,参考线段树求最长递增子序列的思路,先对当前第\\(i\\)行的所有区间,区间询问线段树的最小值,然后取最小值和那个对应的下标转移给\\(f[i]\\)\\(pre[i]\\)。然后对第\\(i\\)行的所有区间,用\\(f[i]-i-1\\)去和区间里的值取\\(min\\),即对区间内的每个数\\(a_i\\)\\(a_i=min(a_i,f[i]-i-1)\\)

对于这部分,懒惰标记有点细节处理:

假设我们要使得区间内\\(a_i=min(a_i,v)\\)

1)如果当前区间的最小值大于\\(v\\),就更新当前区间的最小值和下标,同时把懒惰标记往下打。

2)如果当前区间的最小值小于等于\\(v\\),就直接往下打懒惰标记,不修改当前区间的信息。

最后,枚举\\(f[i]+n-i\\)的最小值,得到最优答案和最后一个没有被删除的行的位置,根据\\(pre[i]\\)往前递归求出所有没有被删除的行。

剩下的就是被删除的行,输出即可。

以上是关于CF1557D.Ezzat and Grid(2200分线段树)的主要内容,如果未能解决你的问题,请参考以下文章

CF 1557D(Ezzat and Grid-线段覆盖)

CF 1557D(Ezzat and Grid-线段覆盖)

cf1557 C. Moamen and XOR

CodeForces - 1557D Ezzat and Grid(线段树+dp)

CF1245D: Shichikuji and Power Grid

CF1245D Shichikuji and Power Grid