【UR #32】王之钦定
感觉能在不会的情况下看懂 UOJ 官方题解的也是神人了。
考虑刻画一个局面的贡献。我们把极长的好的区间都找出来,分析他们的性质。我们不妨设一共有 \(k\) 个极长的好的区间,\(l_1<\cdots<l_k,r_1<\cdots <r_k\),显然区间交只会在相邻区间产生,区间交具有以下性质:
- 区间的交只会存在一种颜色,且一个区间跟它左边的区间和右边的区间的交 不交。我们称只被该区间覆盖的部分为中间部分。
- 在修改次数相同时,长的相邻区间交一定不劣于短的相邻区间交。这句话其实是很突兀的,我们考虑两个相邻区间 \(i,i+1\),考虑这两个区间的并中的位置,在这些位置修改次数相同的情况下,长的区间交一定不劣于短的区间交,手玩一下答案的贡献可得。
- 一个区间中间部分(如果存在),则最左端和最右端一定不修改。否则根据性质二我们可以在修改次数相同的情况下使区间交更长使得答案更优。
接下来我们将利用这些性质去进行 dp,但是在 dp 之前我们发现这些段有很多种类型,我们先把段的种类讨论清楚,对于一个好的区间 \([L,R]\),我们设它与上一个区间交的右端点为 \(l-1\),下一个区间交的左端点为 \(r+1\),我们可以将所有好的区间划分为以下四种情况:
- \(l=r+1\),如 \(111222\)。
- \(l=r\),如 \(111121111\)。
- \(l<r,a_l\ne a_r\),如 \(11112\cdots12222\)。
- \(l<r,a_l=a_r\),如 \(11112\cdots21111\)。
我们设 \(f(i,j,c)\) 表示考虑 \([1,j]\) 这些位置,末尾区间交为 \([i,j]\),颜色为 \(c\) 的最优答案。
转移之前先想好计算答案的方式。由于交的方式很简单,我们考虑容斥算贡献,先算每个区间内随便选的贡献再减去每个交区间内随便选的贡献。
转移第一种区间时,枚举 \(k\) 表示上一个区间交的左端点,我们并不需要关心 \([k,i-1]\) 的颜色,所以可以做到 \(\mathcal{O}(n^3m)\),但是这个就过不了了。
于是需要用到这题的核心思想之一,你发现这题的转移式子中其实是出现了二次函数的,且二次项系数不变,都是 \(1\),那么我们提前把二次项算进 \(f\),就可以将转移形式变成 \(kx+b\) 的形式,从而做到优化。
我们在 \(i-1\) 对每个 \(k\) 找出其一次函数,把凸包维护出来,然后我们发现随着 \(j\) 的增加决策点是单调的,可以直接做到 \(\mathcal{O}(n^2m)\)。
第二种区间的转移也差不太多,但是第三四种区间需要关心好的区间的中间部分,我们利用性质三可以做到 \(\mathcal{O}(n^3m)\),因为你可以直接枚举 \(r\) 表示区间交的右端点,这样颜色是固定的。
我们可以感受到在 dp 时有的东西枚举起来其实存在很多重复和浪费,我们可以考虑将枚举过程也压进 dp。想想哪些状态是必要的。显然我们状态中需要包含 \(r\) 具体是哪个,但是 \(l\) 是谁我们并不关心,也不能关心,不然起不到任何优化效果。然后上一个交区间的左端点我们是需要关心的,因为我们需要算贡献。由于我们知道 \(r\),也就相当于我们知道了一种颜色,我们只需要压另一种颜色 \(c\) 表示钦定 \(r\) 的交区间的颜色为 \(c\)。
于是我们设计辅助状态 \(g(i,j,c)\) 表示 \(r=i\),上一个交区间的左端点为 \(j\),钦定 \(r\) 后面的颜色为 \(c\) 的最优答案,考虑其转移。
这个辅助状态主要是用来装 \(f(i,j,c)\) 对后面的贡献。显然对于一个这样的状态来说,\(l=j+1\),并要求 \(a_{l+1}\ne c\)(这很重要!不然答案会更大),接下来我们需要关心 \(r\)。很明显直接枚举每个 \(r\) 是不对的,我们要充分利用 dp 的优势,分情况讨论。
对于第三类好的区间,我们可以找到 \(j+1\) 之后第一个 \(a_r=c\) 的位置,于是 \(f(i,j,c)\rightarrow g(r,i,a_{l+1})\)。
对于第四类好的区间,我们直接 \(f(i,j,c)\rightarrow g(j+1,i,c)\) 即可。
接下来,我们对于一个 \(g(i,j,c)\) 需要还需要获取前面的信息,我们无法枚举 \(l\),我们可以直接继承 \(i\) 的前驱的状态,即 \(i\) 从右往左第一个满足 \(a_k=a_i\) 的 \(k\),于是 \(g(k,j,c)\rightarrow g(i,j,c)\),算 \([k+1,i-1]\) 的代价是简单的。
不难发现这样第二类好的区间的贡献可以一并算上。
最后考虑 \(g\) 对 \(f\) 的贡献方式。其实很简单,对于 \(g(i,j,c)\),我们可以转移到 \(f(i+1,k,c)\),你发现转移形式其实跟转移一类区间的形式几乎一样,也维护出一个凸包转移即可。
时间复杂度 \(\mathcal{O}(n^2m)\)。
\(\mathcal{O}(n^3m)\) 暴力代码,可以参考转移式。
正解。

浙公网安备 33010602011771号