Educational Codeforces Round 153 VP 记

· · 题解

A Not a Substring

链接

题面翻译

题意(洛谷翻译):有 t 组数据,对于每一组数据,你需要判断能否构造一个只由左右括号组成且长度为已经给定字符串的 2 倍且已经给定的字符串不是子串的合法字符串。注:合法的字符串是左右括号能完全匹配的字符串。如果能,输出 YES ,并同时给出一个合法的答案,如果不能,则输出 NO

人类智慧题。

容易发现输出 NO 当且仅当 s = () ,考虑构造答案。

一种方法是对连续重复字符进行分类讨论,如果出现过连续两个相同括号,就令答案为 ()()()...(),如果没有出现过连续两个相同括号,就令答案为 (((...(())...)))

B Fancy Coins

链接

题面翻译

小丑贪心题。 贪心地尽可能多地放 $k$ 元的硬币,最后不够再用 $1$ 元的硬币补。 就没了。 ## C Game on Permutation [链接](https://www.luogu.com.cn/problem/CF1860C) 题面翻译 两人在一个长为 $n$ 排列 $p$ 上玩游戏,先手初始可以任意选择一个位置(注意先手不能选择一个不能移动的位置),然后他们以先手选择的位置为起点后手先依次交替移动,每次只能向左移动到比当前数字小的位置(即如果 $i<j$ 且 $p_i<p_j$ ,则可从 $i$ 移动到 $j$ ),如果一个人不能移动,则此人获胜,请问先手开始选择有必胜策略的位置的个数。 挺有意思的博弈论。 xx必胜位置:xx从该位置开始走,无论另一个人怎么走,xx都必胜。 xx必败位置:xx从该位置开始走,无论另一个人怎么走,xx都必胜。 先手的必胜位置 是 后手的必败位置,同理 先手的必败位置 是 后手的必胜位置。 容易发现如果先手从当前位置不能走到 先手必胜位置,则当前位置为 先手必胜位置。 反过来,如果当前位置能走到 先手必胜位置,则当前位置为 先手必胜位置。 等价于求以 $ i $ 为结尾的 LIS 长度为 2 的 $ i $ 个数。 可以用 BIT 搞到 $ O(n \log n) $。 另一个想法是记录 $1 \sim i-1$ 先手必胜位置的最小 $ p $,记作 $ pos_1 $,如果 $ p_i < pos_1 $(不能转移),则当前位置为先手必胜位置。 此时需要保证前面有先手必败状态转移,就再记录 $1 \sim i-1$ 先手必败位置的最小 $ p $,记作 $ pos_2 $。则一个位置为先手必胜位置的充要条件是 $ pos_2 < p_i < pos_1 $。 简单维护 $ pos_1,pos_2 $ 即可。 ## D Balanced String [链接](https://www.luogu.com.cn/problem/CF1860D) 题面翻译 给你一个长为 $ n $ 的 $ 01 $ 字符串,每次操作交换两个元素,求最少几次操作能使字符串的顺序对个数与逆序对个数相等。 $ n \le 100 $,一眼 $ dp $。 考虑单个 $ 1 $ 对答案的影响:贡献前面 $ 0 $ 个数个顺序对,贡献后面 $ 0 $ 个数个逆序对。 于是设单个 $ 1 $ 的贡献为 顺序对个数 - 逆序对个数。 容易发现一种交换方案合法当且仅当所有 $ 1 $ 的贡献和为 $ 0 $。 设 $ f_{i,j,k} $ 为 $ 1 \sim i $ 内有 $ j $ 个 $ 1 $,所有 $ 1 $ 贡献之和为 $ k $ 时合法的**与 $s_{1 \sim i}$ 最小的不同个数**。 不难得到转移方程: $$ f_{i,j,k} = \min(f_{i-1,j,k} + [s_i = 1],f_{i-1,j-1,k-val(i,j)} + [s_i = 0]) $$ 其中 $ val(i,j) $ 为第 $ i $ 位之前已经放了 $ j-1 $ 个 $ 1 $, $ i $ 位再放一个 $ 1 $ 时这个 $ 1 $ 的贡献。 容易发现 $ val(i,j) = (i - j) - (tot_0 - (i - j)) = 2(i - j) - tot_0

再把这坨东西带回去:

f_{i,j,k} = \min(f_{i-1,j,k} + [s_i = 1],f_{i-1,j-1,k-2(i - j)+tot_0} + [s_i = 0])

因为每次交换会改变两个不同位置的数,使“与 s_{1 \sim i} 最小的不同个数”减 2

于是答案就是 \frac{f_{n,n-tot_0,0}}{2}

没了。

E Fast Travel Text Editor

链接

图论好题。

考虑图论建模后跑最短路来解决。

前两种操作可以两相邻点之间建边。

第三种操作直接暴力建边显然会 T 掉,注意到字符集大小为 26 ,考虑对每个字母对建 26^2 个虚点,再从虚点向所有该字母连边。

对于所有询问,跑全源最短路显然不现实。把 f t 的路径分成两种:不使用操作三/使用操作三。

前者的答案显然是 | f - t |

对于后者,按照定义,该路径上必定经过一个虚点。再把这条最短路径拆成两部分 f \to c_i c_i \to t ,那么根据最短路的性质,这两条路径也必定是最短路。于是对所有虚点跑 26^2 遍最短路,对于每次查询枚举虚点即可解决后者。

两种情况取 \min 就完了。

F Evaluate RBS

链接

看不懂