trie字典树
摘要:由于笔者不常使用字典树,且整理不够全面,本文只做启发。 trie 字典树,把多个元素的前缀合并起来,用来完成单个元素和集合的匹配。 构造: void insert(trar *str) { int p = 0, len = strlen(str + 1); for (int i = 1; i <=
阅读全文
kmp & fail树 & border
摘要:kmp 经典字符串匹配算法。其实是通过找本身前缀\(i\)的最长border,来实现快速匹配的。 这里给出border的定义:字符串\(s\) 的一个子串既是它的前缀又是它的后缀,则这个子串是它的border(一般不包含本身) kmp通过fail在border上跳,使得每次前面部分的字符串都是相同的
阅读全文
Shift-And & Shift-Or
摘要:Shift And 一种暴力字符串匹配算法,用bitset优化。复杂度\(O(N*M/w)\) 用\(p\)记录当前匹配第几位是成立的,\(skip\)记录字符是\(c\)的有哪些位置。匹配时,\(p\)中第\(k\)位置是成立的,且下一位正好是\(skip\)对应的字符。那么下一位成立。 bits
阅读全文
exkmp(Z函数) & LCP & LCS
摘要:Z函数可以在\(O(n)\)时间内求出自己的所有后缀和本身的LCP(最长公共前缀),和任意字符串\(T\)和其的LCP。 原理就是考虑之前的lcp,可以通过之前的lcp这一位和前缀某一位一致,对应到前缀某一位的LCP,再向右扩展。注意到,右边界最多被扩展1次所以是线性复杂度。 struct Z {
阅读全文
AC自动机
摘要:即在trie上kmp。AC自动机是一种多模式串匹配算法,用于在一个文本串中查找多个模式串。 注意到,AC自动机的\(fail\)也构成了一个树形结构。我们只需要在操作完进行一个离线拓扑排序就不用每次匹配到一个点,暴力跑完所有fail确认是哪些模式串。 struct AC { vector<int>e
阅读全文
序列自动机
摘要:序列自动机 判断字符串\(s\)是否存在序列\(t\)。只需要记录这个位置,后面每个字符出现的最早位置即可\(nxt\)。 求子序列个数 记忆化搜索\(f[x] = \underset {y \in x'son}{\sum} f[y] + 1\) 求两串的公共子序列个数 两个串的记忆化搜搜\(f[x
阅读全文
最小表示法
摘要:最小表示法 字符串 \(S\) 的最小表示为与 \(S\) 循环同构的所有字符串中字典序最小的字符串。 一般用于判断两个字符串是否循环同构。只需要都用最小表示,然后判断即可。 考虑如何构造。这里oiwiki解释的很清楚。就不做过多解释了。复杂度\(O(n)\) int i = 1, j = 2, k
阅读全文
SA & SAM 后缀数组 & 后缀自动机
摘要:终于来到大名鼎鼎的后缀结构了,后缀结果可以解决许多子串问题。后缀结果是字符串经常考察的点,需要重点学习。 SA 后缀排序,是指这个对字符串\(s\)的每一个后缀字符串进行排序,通过处理每个后缀的前缀来解决子串问题。\(SA\):排名为\(i\)对应原字符串下标,\(rk\):下标为\(i\)的后缀排
阅读全文
回文结构 manacher & PAM 马拉车 & 回文树
摘要:manacher 马拉车通过在每个字符间插入一个特殊字符,使得字符串长度为奇数,从而保证每个字符都有中心。在每个中心记录回文串的长度。 马拉车的扩展方式和\(Z\)函数类似。都是通过映射之前已经算过的位置,然后尽可能的向右扩展。复杂度\(O(n)\) 通常马拉车的题目统计回文串需要与其他数据结构结合
阅读全文
Lyndon 分解 & runs
摘要:wcz在2022年集训队论文《浅谈与Lyndon理论有关的字符串组合问题》中做过详细介绍,由于笔者太菜,这里只做简单介绍,并且不做证明。 Lyndon 分解 Lyndon串:对于字符串\(s\),如果\(s\)的字典序严格小于\(s\)的所有后缀的字典序,我们称\(s\)是Lyndon串。 Lynd
阅读全文
基本子串结构
摘要:基本子串结构 xtq 的 2023 年集训队论文《一类基础子串数据结构》提及。能够对子串问题减少一定思维量。相比于 sam 只能固定 endpos 向前扩展,基本子串能方便处理子串前后扩展。 这个东西有点科技了,我不是能有自信能解释清楚,这里指自己认为写的比较详细的博客供参考。crashed | 1
阅读全文