[CSP-S 2025] 谐音替换(replace)题解

[CSP-S 2025] 谐音替换(replace)题解


知识点

Trie,ACAM,Hash。

分析

首先排除一些 corner case:

  1. \(s_1 = s_2\):需要直接扔掉,虽然对于一些算法没有影响,但是保险起见。
  2. \(|t_1| \neq |t_2|\):输出 \(0\) 即可。

现在尝试暴力,从 \(t_1\) 中找可以替换的,然后用 Hash 判断。发现一个条件:设在 \(t_1\)\(t_2\) 中不相等的字符所在位置最大和最小为 \(l,r\),那么替换区间一定要包含 \([l,r]\)

我们想到这个之后,发现其实可以对于 \(s_1,s_2\) 也处理出同样的区间 \([l',r']\)。那么发现,对于能够替换的,一定满足一个条件:\(s_1[l',r'] = t_1[l,r]\land s_2[l',r'] = t_2[l,r]\)

这部分可以考虑 Trie 或者 Hash 处理一下,把满足这个条件的一类放到一起求解。

Hash 算法

直接二分 Hash 即可,复杂度 \(O(L\log{L})\)\(O(L\log^2{L})\),考虑卡常。

Trie 算法

接下来剩下两个条件:

  1. \(s_1[1,l'-1]\)\(t_1[1,l-1]\) 的后缀。
  2. \(s_2[r'+1,|s_2|]\)\(t_2[r+1,|t_2|]\) 的前缀。

那么就变成了 P6344 [CCO 2017] Vera 与现代艺术 - 洛谷 (luogu.com.cn)。复杂度可以是 \(O(n+Q+L|\Sigma|)\)

ACAM 算法

这个算法就显得简单明了很多。

还是与上面一样把中间不一样的区间处理出来,然后设为 \(s_1=ABC,s_2=ADC\),将其转化为 \(A?BD?C\) 的形式(\(?\) 为特殊字符),塞入 ACAM。

查询时 \(t_1,t_2\) 做同样处理,跑多模匹配即可解决,复杂度 \(O(n+Q+L|\Sigma|)\)

反思

  1. 写这题的时候过于焦虑,导致一会想把 T2 先去解决,一会想先打 T4 暴力,一会又先把这题的暴力调出来。
  2. 写暴力的时候错了一个非常弱智的东西。
  3. 这题的核心就是想到处理出中间不同的部分,我想到了处理出 \(t\) 的不同部分,但是没有想到把 \(s\) 的也处理出来。
  4. 匹配题要多联想有关相同的性质,例如这题 \(t\) 上的性质可以转移到 \(s\) 上。
posted @ 2025-11-13 14:56  Add_Catalyst  阅读(10)  评论(0)    收藏  举报