【W的AC企划 - 第十期】字符串哈希
往期浏览
题单
1003F(\(\tt *2200\);字符串-哈希、字符串-KMP、暴力)
string - hashing List #5 | 比较难受的一题,原先的字符串板子传递变量的时间过慢导致一直超时,但是难度并不是很高。
首先观察到单个字符串长度极长但是数量很少,于是想到使用字符串哈希将总长度缩小,属于比较典的思路,使用 map
即可轻松做到这一点;随后暴力枚举全部匹配情况后依次统计次数即可,借助 KMP 可以在 \(\mathcal O(N^3)\) 完成。注意,如果使用 find
函数规避 KMP ,那么理论最坏复杂度会上升到 \(\mathcal O(N^4)\),我一开始是由于读错了题,以为至多可替换两段内容,于是没有使用 KMP,导致超时。
另外还有一点需要注意的是,上述的复杂度需要简单修改 KMP 函数使之能够对哈希后的数组进行匹配,如果使用 to_string
函数对哈希后的数组再处理回字符串后运行 KMP(没错,我一开始真的这样写了),复杂度会上升到最坏 \(\mathcal O(N^2 \cdot \sum_{i=1}^{200})\),这样依旧会超时。
另外,注意到我们是暴力枚举后进行匹配,未被枚举到的部分其实不需要进行匹配,所以本题有一个修改 KMP 匹配范围进行优化的方法,使得单次只匹配使用到的那部分内容,可以简单学习。根据这一优化方式,抽象了一个“统计原串中某个子串重复出现的次数”的板子。
7D(\(\tt *2200\);字符串-哈希)
string - hashing List #4 | 哈希判回文,较模板。单哈希即可通过,双哈希有超时风险。观察到有较高效的做法 See 。
25E(\(\tt *2200\);暴力、字符串-哈希、字符串-KMP)
string - hashing List #3 | 暴力枚举后运行两个字符串算法,较模板。写这题的过程中综合了之前做过的字符串哈希的题目形成了一个较为系统的哈希相关封装。
1200E(\(\tt *2000\);字符串、暴力、哈希)
string - hashing List #2 | 字符串后缀哈希,感觉是很典的题目。
514C(\(\tt *2000\);字符串、数据结构-字典树、搜索、暴力、哈希)
注意到串仅由三个字母构成。方法一是很显然的,建立字典树后在树上进行搜索匹配串:针对匹配串的每一位,暴力枚举其三种不同构成,最终以 \(\mathcal 3\cdot \sum N\) 的复杂度完成搜索。针对该方案有如下优化:\(\tt ^1\) 不使用 auto
进行搜索,而是直接用单独的函数进行,前者在实现上花费的时间更长一些;数组不留余量,使用 \(\tt 0-idx\) 法,这一优化可以提速近乎一倍,推测原因是减少了数组跳转的次数,应当引起注意。
string - hashing List #1 | 下面介绍字符串方面的方法:字符串哈希。本题使用单哈希需要将模数固定在 \(10^{10}\) 量级以上,不然会撞;如果是双哈希则没有特别的限制。属于字符串哈希的模板题,但是需要手写一个 \(\mathcal O(1)\) 进行某一位修改的函数(本质上是与方法一暴力修改一样的思路),比较考验对哈希过程原理的理解。