摘要: 后缀树 AC 自动机中文本串未知而模式串已知,而后缀树与之相反,文本串已知而模式串未知,我们需要利用某种东西维护文本串所有子串的信息。 首先可以有暴力的想法,我们把文本串所有的后缀都扔进 Trie。然而这样结点个数是 \(O(n^2)\) 的,我们需要继续压缩信息。 我们在每个后缀的最后加上一个特殊 阅读全文
posted @ 2025-04-18 18:59 RandomShuffle 阅读(56) 评论(1) 推荐(1)
摘要: 后缀数组。要实现的是后缀排序,就是把 \(s\) 的所有后缀排序。包含两个数组(或者可以视作映射):\(sa_i\),第 \(i\) 小的后缀在原串中的开始位置;\(rk_i\),在原串中开始位置为 \(i\) 的后缀(以下称之为后缀 \(i\))的排名。这两个互为反函数,复合一下就消了:\(sa_ 阅读全文
posted @ 2025-04-18 18:51 RandomShuffle 阅读(49) 评论(0) 推荐(0)
摘要: 回文自动机高度压缩了字符串中所有回文子串的信息,维护了原串中所有本质不同的回文子串。 PAM 的结构可以看作两棵树,但实际上是一棵。有两个根,分别是奇根 \(odd\) 和偶根 \(even\)。\(odd\) 上连着所有长度为奇数的回文子串,自身长度置为 \(-1\)。\(even\) 上连着所有 阅读全文
posted @ 2025-04-18 17:08 RandomShuffle 阅读(24) 评论(0) 推荐(0)
摘要: 可以求以位置\(i\)为中心的最长回文子串(其半径也等于以位置\(i\)为中心的回文子串个数。) 可以观察到一件事:奇回文串的回文中心为一个字符,偶回文串的回文中心为字符间的空隙。于是想办法统一奇偶回文子串。 我们可以在每两个字符的间隔中插入一个特殊字符(如#,首尾也要插入)。并且在构造好后再次在首 阅读全文
posted @ 2025-04-18 17:01 RandomShuffle 阅读(12) 评论(0) 推荐(0)
摘要: AC自动机结合了Trie的结构和KMP失配的思想,解决的是多模式串匹配问题。 步骤: 将所有模式串构成Trie 对每个Trie上的节点构造失配指针\(fail\)。 之后就可以利用构建出的AC自动机解决各种问题。 这里的Trie的节点表示一种状态,状态是某个模式串的前缀(即从Trie上的节点走到根经 阅读全文
posted @ 2025-04-18 16:59 RandomShuffle 阅读(36) 评论(0) 推荐(0)
摘要: 是各种自动机的基础。 数据结构里也会讲。这里只讲Trie作为字典使用的情形。 板子: inline void ins(string s,int v){ int u=0; for(int i=0;s[i];++i){ int c=idx(s[i]); if(!ch[u][c]){ memset(ch[ 阅读全文
posted @ 2025-04-18 16:57 RandomShuffle 阅读(22) 评论(0) 推荐(0)
摘要: 记录了一个后缀和原串的LCP长度的信息。有点和后缀扯上关系了。 也有人叫它扩展KMP,但其实和KMP没有太大关系。 对于字符串\(s\),定义\(z_i\)表示\(suf_{s,i}\)与\(s\)的最长公共前缀(LCP)的长度。我们可以\(O(n)\)求出\(z_i\)。 类似KMP,我们同样递推 阅读全文
posted @ 2025-04-18 12:56 RandomShuffle 阅读(53) 评论(0) 推荐(0)
摘要: 感觉实力已经达到了不会再写错KMP的地步了,但是还是记一下。 border:若字符串\(s\)的真前缀\(pre\)与真后缀\(suf\)满足\(pre=suf\),则称之为\(s\)的一个border。 周期:对于整数\(p=1,2,3,\dots,|s|\),若对于\(\forall i\in[ 阅读全文
posted @ 2025-04-18 12:53 RandomShuffle 阅读(16) 评论(0) 推荐(0)