AGC056C

题面

你需要构造一个长度为 \(n\)\(01\)\(S\),满足给定的 \(m\) 个条件,每个条件形如:

  • \(S[l,r]\)\(0,1\) 的个数相等。

并且最小化 \(01\) 串的字典序。

数据范围:\(n\le 10^6,m\le 2\times 10^5,2|(r-l+1)\)

题解

首先,如果你把 \(0\) 看成 \(-1\) ,记 \(s_i\) 为前缀和,那么一个条件 \((l,r)\) 就可以表述为约束 \(s_{l-1}=s_r\)

此外,约束还有一个 \(s_i\) 本来的限制 \(s_i-s_{i-1}=\pm 1\)

但是这又有什么用呢?

这时候就要使用神奇的算法:差分约束!

\(s_{l-1}=s_r\) 就可以变成 \(l-1\)\(r\) 连了边权为 \(0\) 的边。

但我们怎么转换 \(s_i-s_{i-1}=\pm 1\) 这个限制呢?

因为差分约束的形式是 \(a_x-a_y\le z\) ,我们考虑能不能把 \(s_i-s_{i-1}=\pm 1\) 转换成 \(|s_i-s_{i-1}|\le 1\) ,也就是 \((i,i-1,1),(i-1,i,1)\)

仔细想一想,发现好像是可以的!

为什么?

因为 \(2|(r-l+1)\) ,所以是不可能出现 \(s_i=s_{i-1}\) 的。

所以可以用dij得到一组解。

但是题目还要求字典序最小,怎么搞?

可以把顺着走看成是选 \(0\) ,逆着走看成是选 \(1\) ,观察最短路的过程,对于一个约束,我们一般会在前一部分顺着走,后一部分逆着走,直接最短路跑出来的解是字典序最大的解,所以我们取反就会变成字典序最小的点。

启发

  • 对于 构造 \(01\) 串并且满足一些性质的题,可以往查分约束上想。
posted @ 2022-07-08 09:17  qwq_123  阅读(85)  评论(0编辑  收藏  举报