CF1458D - Flip and Reverse 题解

我们考虑前缀和,\(\texttt0\)\(-1\)\(\texttt1\)\(1\),那么能修改的区间要满足 \(Sum_{l-1}=Sum_r\)。(想不到 * 1)

然后我们考虑一次操作是在 \(Sum\) 上做了什么。反转的话,那就是关于 \(y=Sum_{l-1}\) 对称了一下;翻转可以想象一下,把折线的最右边一段移到最左边,这是中心对称了,于是就是既上下又左右对称。那么两者合起来就是左右对称,也就是把 \(Sum_{l\sim r}\) 这一段翻了个个儿。

然后我们考虑若干次操作能干些什么。注意到一次操作只会改变前缀和值们的访问顺序,而不会改变值,所以我们可以想象成一条从头访问到尾的链,然后操作就是改变一些前驱后继。那么一次操作本质上就是把 \(l-1,r\) 之间的路径的边全部反向,然后把 \(l-1,r\) 交换前驱后继。

我们盯着某一个值看,提炼出这个值在 \(Sum\) 里的所有位置,那么任意两个之间都可以反应。注意到只有在关键位置处才会有方向的转折,于是我们 dark 把相邻关键点之间的缩到一起,并且记录方向,那么可以表示成这种形式:\(1\to +1.5\to 2\to +2.5\to 3\to \cdots\),其中整数表示关键点,小数表示缩起来的东西,正负号表示方向,一开始就是如上状态。注意到所有关键点的值都是一样的,而且永远是一个关键点、一段浓缩饼干这样排列,于是我们可以不管关键点,只看浓缩饼干的排列方式。一个显然的结论:任意排列、每个任意方向都可以做到。构造方案就是先随意翻,然后再逐个击破。

那么我们可以把值当作节点建图。(想不到 * 2)

考虑先建有向边 \(Sum_i\to Sum_{i+1}\)。然后对于每个值,以它为关键值的作用显然就是经过它的环们。注意到把在环上的边建成无向边恰好符合要求,可以任意顺序任意方向的走。那么显然字符串和该混合图的欧拉回路 / 路径成双射关系,因为一条边就代表一个字符,这还是很好理解的。

于是现在我们就需要求混合图字典序最小欧拉回路 / 路径。但是我们连混合图求欧拉回路 / 路径都不会,必须要用网络流/jk。但这其实是个幌子。显然一条边是无向边当且仅当它在 \(Sum\) 里两边有相同值。那么我们考虑所有有向边区间,它们内的值两两不同,而且跟所有无向边两端的也都不同(可以反证)。那把有向边改成无向边又何妨?反正只有一种走法。

那么如何求字典序最小的欧拉路呢?注意到另外一个性质:只有编号相邻的两个点会连边,那么贪心就可以了,每次选 \(\texttt 0/\texttt1\),维护连通性(这个很好维护,利用上述性质)和奇点个数即可。

code

posted @ 2020-12-23 21:52  ycx060617  阅读(225)  评论(0编辑  收藏  举报