Happybob's String Challenge

Happybob's String Challenge(口胡 ver)

做法来源:我、hb、题解

大致按体感质量分类,内部按题目编号排序。

Good Problems

H. CF1562E Rescue Niwen!

Tag: 动态规划、推性质

显然对于每一个后缀,我们选择的都是它在一个区间中的前缀(可能为空)。

进一步分析,发现我们选择的一定是一个后缀中的前缀。

因此可以 dp,设 \(f_{i, j}\) 表示当前最后的是 \(i\) 后缀的 \(j\) 前缀。有转移 \(f_{i, j} \gets f_{i, j - 1}\)。还有对于字典序严格 \(\gt i\) 的 \(k\),有 \(f_{k, \text{lcp}(i, j)} \gets f_{i, n - i + 1}\)。

K. CF2172H Shuffling Cards with Problem Solver 68!

Tag: 变种 SA

不妨假设原题为 \(0\text{-index}\)。设 \(p_i\) 表示在第 \(i\) 个位置的牌原来的编号,则每次操作相当于把 \(p_i\) 的最低位转到最高位。所以显然它有 \(k\) 的周期。更进一步,我们可以直接预处理出旋转 \(t\) 次的编号 \(p_i\)。

那么如果一开始选择了循环位移 \(j\),则最终位于第 \(i\) 个位置的牌就是 \((j + p_i) \bmod k\)。

考虑对它进行倍增排序。设 \(\mathit{rk}_{i, j}\) 表示从 \(i\) 开始的循环位移,若只关心前 \(2^j\) 个字符,它排第几名。发现倍增只需要把所有 \(i\) 按二元组 \((\mathit{rk}_{i, j}, \mathit{rk}_{i + p_{2^j}, j})\) 进行排序即可。

P. CF1038F Wrap Around

Tag: KMP-AM

考虑判定。建出 \(s\) 的 KMP-AM,然后从 \(0\) 开始用 \(t\) 跑 KMP-AM,假设走到 \(x\)。接着再从 \(x\) 开始跑,最后肯定还回到 \(x\)。如果后面 \(x \leadsto x\) 之间经过了 \(n\),那就是合法的。

因此可以枚举 \(x\),然后在自动机上 dp,容易做到 \(O(n^3)\)。

因为一定要经过 \(n\),所以可以改为从第一个 \(n\) 往两边 dp,可以做到 \(O(n^2)\)。

或者正难则反,计算不包含 \(s\) 的方式,相当于把自动机中 \(n\) 这个点扣掉,然后计算长度为 \(n\) 的环的数量。有科技能做到 \(O(n \text{polylog})\)。

V. AGC026E Synchronized Subsequence

Tag: 贪心

我们先将序列划分成若干个 \(a, b\) 数量相等的子段。可以证明,最终的答案里一个子段要么全不选,要么选择与其他子段独立。接下来考虑对一个子段求答案。

设 \(a_i, b_i\) 表示第 \(i\) 个 \(a, b\) 所在的下标。可以发现一个子段要么全部 \(a_i \lt b_i\),要么全部 \(a_i \gt b_i\)。

对于 \(a_i \lt b_i\) 子段,选出来的开头显然为 \(a\),所以先选上 \(a_1, b_1\)。因为我们已经做到第二个字符是 \(b\) 了,所以 \((a_1, b_1)\) 中的所有 \(a\) 都不选。在 \(b_1\) 之后,因为我们还希望尽量长,所以又是一个类似的子问题。最终能得到一个 \(abab\dots\) 型字符串。

对于 \(b_i \lt a_i\) 子段,可以发现若选择了 \(b_i, a_i\),则再选择 \(b_{i + 1}, a_{i + 1}\) 一定不会劣。因此选择的 \(i\) 一定是一段后缀,可以枚举并判断。

最终变为有若干个字符串,要从中选出若干个按原顺序拼接,使得字典序最大。可以从后往前贪心,能加就加。

Y. ARC175F Append Same Characters

Tag: 字典树、拼接比较引理

可以先做完第一种操作再进行第二种操作。第二种操作所需的次数就是逆序对个数。

对于两个串 \(A, B\),不妨设 \(A\) 比 \(B\) 短。如果在前 \(\lvert A \rvert\) 个字符就有区别了,那逆序关系肯定不会改变了,就不用管了。否则,设 \(B = AY\)。

假设我们插入了 \(X\),易得 \(A, B\) 之间的关系发生变化(也就是 \(AX \gt AYX\))等价于 \(X \gt Y^\infty\)。

所有的 \(Y\) 也就是所有 \(B\) 的后缀(也就是字典序上以某个字符串结尾的祖先后代链)。因为总长是有保证的,所以我们可以对每个 \(Y\) 单独计算它的贡献。也就是计算 \(B\) 在序列中的下标,位于哪些 \(A\) 的后面、前面,可以在 vector 上二分。然后,我们只需要枚举 \(x\) 属于哪两个 \(Y\) 之间就行了。

比较两个 \(Y^\infty\) 之间的大小,可以用拼接引理转化,变为比较 \(Y_1Y_2\) 和 \(Y_2Y_1\)。另外 \(X\) 的最短长度也就是 \(\text{lcp}(Y_1^\infty, Y_2^\infty) + 1 = \text{lcp}(Y_1Y_2, Y_2Y_1) + 1\)。注意特判 \(Y_1Y_2 = Y_2Y_1\) 的情况。

Medium or Harder Problems

E. CF1968G2 Division + LCP

Tag: Z 函数、调和级数、序列并查集

注意到第一个串是前缀,所以这些 LCP 只有 \(O(n)\) 种取值。考虑枚举 LCP 的长度 \(l\),那么一个前缀 \(i\) 合法当且仅当 \(Z_i \ge l\),也就是合法的是一个区间。

因此我们可以按 \(l\) 从小到大扫描,每次 ban 掉 \(Z\) 太小的位置,然后用序列并查集贪心地求出最多能划分成多少段。最后再将得出来的东西转置一下就得到答案了。

如果把并查集改成启发式合并,就能得到 \(O(n\log n)\) 的做法。

G. CF1550E Stringforces

Tag: 状压 dp

注意到 \(k\) 很小,猜测复杂度中 \(k\) 是指数。

考虑二分答案 \(d\),然后可以从左往右 dp。设 \(f_S\) 表示,要使 \(S\) 这些字母都选出了长度为 \(d\) 的子串时,左端点最小是多少。check 时需要对于一个字母 \(c\) 和位置 \(l\),快速找到第一个在 \(l\) 右侧,只含 \(c\) 和 ? 的区间。可以预处理出来。具体相当于一个字母会把别的字母包含这个位置的区间都 ban 掉。

I. CF1437G Death DBMS

Tag: 失配树、树剖

子串也就是前缀的后缀。也就是在跑 ACAM 的时候,每个节点在 fail 树上的所有祖先。

于是问题变为,树上单点修改,求到根路径 \(\min\)。树剖线段树维护即可。

当然也存在聪明的办法可以离线之后扫描线少一个 \(\log\),我不会。

M. CF1827C Palindrome Partition

Tag: 贪心

可以发现若一个串可以划分成若干个偶回文串,则一定能通过贪心选最短的方式划分。原因是若一个偶回文串存在前缀是偶回文串,则能对称地将其分割。

因此建出转移的树就行了,答案为每个点的深度之和。

Q. CF2092F Andryusha and CCB

Tag: 调和级数

观察到我们只需要知道一个连续段长度是 \(=1\) 还是 \(\ge 2\),分别称为 \(1, 2\) 连续段。

枚举最终的美好度 \(c\),则当 \(c \ge 2\) 时,所有 \(1\) 连续段只会被恰好一个包含,\(2\) 可能被拆成两半。

接着枚举划分的段数 \(k\)。我们可以贪心地求出能划分成 \(k\) 段的最短、最长前缀 \(l, r\),则区间 \([l, r]\) 中每一个前缀都可以划分成 \(k\) 个美好度为 \(c\) 的子串。容易通过调整法说明(将最后一个分裂的 \(2\) 完整归为左边即可使 \(r\) 增加 \(1\))。

可以证明对于一个字符串,若确定了每一段的美好度 \(c\),则划分的段数是固定的。因此上面的方法不会计重。

\(k, c\) 的段数显然是调和级数,所以总复杂度为 \(O(n\log n)\)。

Plain or Easy Problems

A. ABC284F ABCBAC

Tag: 哈希

注意到 \(S\) 长度固定,所以可以枚举 \(i\) 然后用哈希判断。

B. ABC377G Edit to Match

Tag: 字典树

我们可以先加入一个空串。两个字符串的距离就是字典树上的距离。直接在树上维护即可。

C. CF1729G Cut Substrings

Tag: 哈希、动态规划

显然可以动态规划。设 \(f_{i, j, k}\) 表示当前已经处理完 \(s\) 的前缀 \(i\),在接下来 \(j\) 个字符中必须要移除一次 \(t\) 的出现(否则更早的出现就消除不掉了),已经移除了 \(k\) 次。直接转移即可做到 \(O(n^3)\)。

D. CF1721E Prefix Function Queries

Tag: KMP-AM

原题相当于我们动态加入数,求新的部分的 KMP 数组。但是 KMP 的复杂度是均摊的,这里显然不能暴力求。于是可以用 KMP-AM 来代替,即预处理出失配的转移。

Strange or Dull Problems

F. ABC272F Two Strings

Tag: SA

SA 板子?

L. ABC312H snukesnuke

Tag: 周期

不难求出所有串的最小整周期,不同周期的串之间互不影响。于是问题变为,维护集合 \(S\),每次加入一个数 \(x\),找到不在 \(S\) 中最小的 \(x\) 的倍数加入 \(S\)。

因为加入的 \(x\) 的总和是有保证的,所以可以对每个 \(x\) 都开一个序列并查集来维护。

S. CF932G Palindrome Partition

Tag: PAM

原题的划分,等价于在字符串 \(s_1s_ns_2s_{n - 1}\dots\) 上进行偶回文子串划分。

然后就是在 PAM 上,借助“回文 border 引理”来进行转移。

W. CF1815E Bosco and Particle

Tag: 动态规划

混入其中的非字符串题。本题唯一字符串部分就是求出每个串的最小周期。

首先把所有 \(s_i\) 换成最小周期,这显然不影响答案。观察到穿过 \(i\) 的次数是 \(s_i\) 中 \(0\) 的个数,所以如果有奇数个的话,我们再执行 \(s_i \gets s_is_i\)。

我们可以对每个 \(i\) 计算,单看 \(s_i\) 这个门,在一个周期中向左、向右发射粒子的次数 \(a_i, b_i\)(其实就是不断累计,每遇到一个 \(0\) 就改为在另一个数组中 \(+1\))。

考虑从后往前 dp。设 \(T_i\) 表示 \(i\) 到后面所有门,需要从左侧射入几次粒子才形成周期,\(f_i\) 表示期间需要的总时间。

当加入门 \(i\) 时,显然有 \(a_i \mid T_i\)。另外还有 \(T_i \times \frac{b_i}{a_i} \mid T_{i + 1}\)。因此有 \(T_i = \text{lcm}(a_i, T_{i + 1}a_i / b_i)\)(当然后面这个可能是小数,我们直接把它的分母忽略就行了)。\(f\) 就是 \(f_i = 2T_i + \frac{T_ib_i}{a_iT_{i + 1}}f_{i + 1}\)。

维护 \(\text{lcm}\) 可以直接维护各个质数的指数,乘除的话用 \(\bmod 998\) 意义下的逆元就行了。

Sh*t Problems

J. CF1466G Song of the Sirens

???

N. CF1310C Au Pont Rouge

???

O. CF1923F Shrink-Reverse

注意到翻转次数不超过 \(1\) 次。

R. CF2201E ABBA Counting

Tag: 卷积、容斥

先考虑一个相对简单的问题:对划分方案计算数量。

显然 \(A+B\) 的总和是确定的。\(A+B\) 与 \(B+A\) 的关系是循环位移,所以我们要计算的就是,对于每一个后半部分的循环位移,计算与前缀匹配的方案数。

将后半部分反过来并复制一遍,可以发现对应位置相等变成了下标和固定的位置相等。于是可以用卷积算出贡献。

但原题是对 \(S\) 计数。考虑容斥。一个 \(S\) 会被计算多次,当且仅当它存在对应的周期。所以只需要对每个周期分别计算一次即可。

T. CF1535F String Distance

Tag: 平衡复杂度

首先两个串若能转化,则字符集要相同。对于一个等价类内的两个串,显然距离不超过 \(2\)(可以对两个都排序一次)。所以我们只需要计算次数为 \(1\) 的对的数量。

显然我们会在字典序较大的那个串选择一个区间进行排序。

一种 \(O(n^2)\) 的求法是,枚举两个串 \(s_1, s_2\),计算它们的 LCP, LCS,中间的部分就是需要排序的。我们只需要检查中间的部分是否有序就行了。

还有一种 \(O((\sum L)^3 / n^2)\) 的求法,就是枚举一个串上的子区间,计算排序后有几个串和它相同。

因此在一个等价类的 \(n \le (\sum L)^{\frac 34}\) 时采取第一种,否则采取第二种即可平衡。

X. CF1598G The Sum of Good Numbers

Tag: 哈希

因为不存在 \(0\) 的性质,所以最高的进位不超过较短数的最高位 \(+1\)。所以较长串的长度要么是 \(\lvert x\rvert\),要么是 \(\lvert x\rvert-1\)。

然后枚举即可。

Z. ABC280H Substring Sort

Tag: SA

又来一个板子。

Other

U. CF2249E2 String

不会。

posted @ 2026-10-11 15:23  cosf  阅读(6)  评论(0)    收藏  举报