题解:AT_abc435_g [ABC435G] Domino Arrangement
前言
本文同步自洛谷专栏,题目传送门。
这是一篇复杂度 \(\mathcal{O}(m\log{m})\) 的线段树题解,此外,你还需要会一些矩阵知识,或许会好理解一些。
更新:对线段树做法进行改进,获得了线性做法,但是需要会逆矩阵。
分析
题面的限制相当于把两个同色的捆绑放置。
考虑设 \(dp_{i,j}\) 表示已经确定了前 \(i\) 位,第 \(i\) 位为 \(j\) 的情况(\(j=0\) 表示未染色)。
那么有转移(刷表法,箭头表示加过程):
注:\(j=0\) 是允许的,第一条中还有限制,要求 \(i,i+1\) 位可以放 \(k\)。
暴力转移或许会收获 \(\mathcal{O}(nm^2)\) 的复杂度,考虑优化,数据范围允许使用线段树,考虑线段树维护 \([1,m]\),需要两棵线段树分别表示奇偶位。
对于第二个转移,可以记录全局和 \(sum\),特殊维护 \(dp_{i,0}\)。
对于第一个转移,可以表示为如下形式(此处箭头表赋值):
但是需要注意,有些结点不可转移,则在线段树上需要维护 \((sum,cnt)\) 表示区间和、区间有效下标数(认为是一个行向量)。
用矩阵表示转移。
则打懒标记即为乘上一个矩阵:
此外,线段树还需要支持单点激活、删除(\(cnt\) 置 \(1,0\) 并视情况赋初值)。
全局的初始状态为 \(dp_{0,0}=1\)。
实现
使用矩阵实现可能被卡常,手玩一下矩阵可以发现,转移矩阵右边两数是不变的,可以省掉转移,可以见代码,赛后订正记录。
线性做法
观察代码实现后,发现:每次仅全局查询、全局打标记。那么,可以考虑标记永久化。
即只需在根节点处维护一组标记即可。
然而,存在一个问题:线段树的单点激活是与标记无关的赋值操作。
我们需要保证某下标的 \((sum,cnt)\) 乘上根处的标记后得到真实的值,激活时求解逆矩阵即可。
这里逆矩阵非常容易求解,该矩阵有两个定值,一个值只能取 \(-1,1\) 中的一个,可以推一下,下面直接给出。
那么线段树可以仅保留根和叶子,复杂度做到线性,记录。

浙公网安备 33010602011771号