随笔分类 -  字符串

摘要:这个题BST考场爆切然后教我的,%%%。 首先我们发现生成的数列一定是原序列的一个子序列,然后有要求本质不同的序列个数,这就让我们往子序列自动机上靠。我们先看一下对 \(a_i,a_{i+1}\) 操作的几种不同的后果: \[ 00\to 0\\ 01\to 1\\ 10\to 1\\ 11\to 阅读全文
posted @ 2020-08-04 13:16 With_penguin 阅读(235) 评论(0) 推荐(0)
摘要:这道题的字符集是 \(O(n)\) 的,正常的子序列自动机时空复杂度都无法接受。 所以我们考虑用 \(vector\) 来代替这个过程。用 \(vector\) 记录每个字符出现的位置,然后进来一个字符就二分这个字符下一次出现的位置。时间复杂度 \(O(nlogn)\)。 代码: #include< 阅读全文
posted @ 2020-07-30 16:33 With_penguin 阅读(112) 评论(0) 推荐(0)
摘要:OI Wiki 子序列自动机的每个状态表示当前位置结尾的字符串中第一次出现的字符串。状态数 \(n+1\) ,转移数 \(O(n\times \sum)\),其中 \(n\) 为字符串长度,\(\sum\) 为字符集大小。 应用 判断一个字符串是否是另一个字符串的子序列 对第二个序列建立子序列自动机 阅读全文
posted @ 2020-07-30 16:30 With_penguin 阅读(748) 评论(0) 推荐(0)
摘要:最小表示法模板题: 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=300009; int n,a[N]; void init 阅读全文
posted @ 2020-07-30 13:23 With_penguin 阅读(125) 评论(0) 推荐(0)
摘要:OI WIki 找出一个字符串的最小循环同构,就是最小表示法。 由于我们只想要找到最小的,所以可以用打擂台的方式进行筛选。但是如果每个串都逐位比较的话,发现会被 \(aaa\cdots aab\) 这样的数据轻松卡成 \(O(n^2)\)。 考虑优化,我们发现如果有两个相同的很长的子串,复杂度就难以 阅读全文
posted @ 2020-07-30 13:21 With_penguin 阅读(152) 评论(0) 推荐(0)
摘要:还是求几个串的最长公共串。 但是由于数据范围的原因,用后缀数组可能会T,所以现在介绍一种后缀自动机的解法。 首先考虑两个串的公共串怎么求(假设分别为 \(S\)、\(T\))。对 \(S\) 建立后缀自动机,把 \(T\) 放在后缀自动机上跑,如果没有转移就跳后缀 \(link\)。然后在每个节点记 阅读全文
posted @ 2020-07-22 23:38 With_penguin 阅读(88) 评论(0) 推荐(0)
摘要:对 \(T\) 的每个位置进行考虑。 设 \(f_i\) 表示以 \(T\) 的第 \(i\) 个位置结尾的字符串(\(S_k\))的个数 设 \(g_i\) 表示以 \(T'\) 的第 \(n-i+1\) 个位置结尾的字符串(\(S_k'\))的个数(其中 \(T'\) 表示 \(T\) 的反串, 阅读全文
posted @ 2020-07-22 22:49 With_penguin 阅读(117) 评论(0) 推荐(0)
摘要:首先把这些串排成一排(中间用随便什么符号隔断一下),然后跑一遍后缀数组。 我们把这些后缀排序后,发现一段区间可以对答案有贡献当且仅当 \(n\) 个字符串的任意位置都在这个区间出现过,然后 \(two\_point\) 跑一遍,可以用你喜欢的数据结构维护 \(height\) 的最小值。 代码: # 阅读全文
posted @ 2020-07-19 23:16 With_penguin 阅读(169) 评论(0) 推荐(0)
摘要:OI Wiki 一些重点: 后缀自动机形成的图是一个DAG(许多题可以利用这个性质DP) 这个DAG上的任意一条路径是一个子串 endpos等价类可以由parent树的子树合并得到(再加上这个节点本身) 注意后缀自动机的源点代表空串,很多题需要单独处理 例题: luogu P3804 【模板】后缀自 阅读全文
posted @ 2020-07-19 23:09 With_penguin 阅读(89) 评论(0) 推荐(0)
摘要:当 \(t=0\) 时:考虑 \(dp[i]\) 表示到了后缀自动机上的点 \(i\),往后走还能形成多少子串。转移很显然:\(dp[i]=1+\sum dp[nxt_i]\)。加一是因为可以直接停下,\(nxt_i\) 代表 \(i\) 到 \(nxt_i\) 有一条边。然后想主席树之类的查询就可 阅读全文
posted @ 2020-07-19 23:08 With_penguin 阅读(111) 评论(0) 推荐(0)
摘要:每个子串的出现次数就是其后缀自动机上所在节点的endpos等价类集合的大小。 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N= 阅读全文
posted @ 2020-07-19 22:57 With_penguin 阅读(121) 评论(0) 推荐(0)
摘要:字典树 Trie的维护可以看做一个自底向上的更新,每次更改值时只关注叶子节点,有叶子节点逐层向上更新。 例题: luogu P6018 [Ynoi2010]Fusion tree 题解 luogu P6623 [省选联考 2020 A 卷] 树 题解 阅读全文
posted @ 2020-07-14 21:31 With_penguin 阅读(103) 评论(0) 推荐(0)
摘要:考试前几天刚刚考了01trie整体加一这个trick,但是我当时口胡没写。考场上乱写写了一年没写对。。。 这个题的做法就是对每个点维护一个01trie,然后每次向上合并就啥也没有了。 代码: #include<cstdio> #include<cstring> #include<iostream> 阅读全文
posted @ 2020-07-14 21:30 With_penguin 阅读(118) 评论(0) 推荐(0)
摘要:之前膜你赛好像考过好几次这种类型的题目,但我太菜了一直没听懂。 有个很常见的trick是统一维护一个点所有儿子的异或和,单独维护父亲。然后再上能维护全局+1的01trie这题就做完了。 代码: #include<cstdio> #include<cstring> #include<algorithm 阅读全文
posted @ 2020-07-14 21:19 With_penguin 阅读(152) 评论(0) 推荐(0)
摘要:容易发现这就是后缀排序后连续 \(k\) 个后缀的 \(lcp\) 的最小值的最大值,用单调队列跑一遍 \(height\) 数组即可。 代码: #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #in 阅读全文
posted @ 2020-07-12 20:37 With_penguin 阅读(151) 评论(0) 推荐(0)
摘要:首先把两个字符串拼在一起,中间夹一个不可能出现的字符。 然后就是一个简单容斥,我们假设给的字符串为 \(S_1\) 和 \(S_2\),新拼成的字符串为 \(S\),那么答案就是求 \(same(S)-same(S_1)-same(S_2)\),其中 \(same(s)\) 表示 \(s\) 这个字 阅读全文
posted @ 2020-06-25 11:43 With_penguin 阅读(175) 评论(0) 推荐(0)
摘要:对于一个字符串$S$,我们记后缀 \(Suf_i\) 为从 \(i\) 开始一直到末尾所形成的子串(\(S_iS_{i+1}...S_{len}\))。 现在我们要对所有后缀按照字典序排序。记 \(sa_i\) 表示排名第 \(i\) 的后缀的起始位置,\(x[i]\) 表示 \(Suf_i\) 的 阅读全文
posted @ 2020-06-18 07:43 With_penguin 阅读(84) 评论(0) 推荐(0)
摘要:模板题,代码如下: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N=1000009; int n,m,x[N],y[N],c[N],s 阅读全文
posted @ 2020-06-18 07:30 With_penguin 阅读(48) 评论(0) 推荐(0)
摘要:AC自动机是Trie树与KMP思想的结合。用于多模式串匹配。 和KMP一样,它的原理就是:对所有模式串建一个Trie。任意一个串扔进去,得到的就是在Trie树上最长能匹配的后缀,我们把文本串的每个前缀依次加进去(前缀的后缀就是子串),就能得到模式串与文本串的关系了。 考虑到怎么实现这个功能:和KMP 阅读全文
posted @ 2020-06-18 07:06 With_penguin 阅读(71) 评论(0) 推荐(0)
摘要:KMP算法用来求单模式串匹配。 简单来说,你需要给你的模式串计算一个 \(nxt\) 数组,使得 \(nxt[i]\) 是长度为 \(i\) 时的最长公共前后缀。 匹配到文本串的一个位置 \(i\) 时,相当于把文本串长度为 \(i\) 的前缀拿出来,找它的最长后缀(前缀的后缀即是子串)使得能与模式 阅读全文
posted @ 2020-06-17 06:43 With_penguin 阅读(40) 评论(0) 推荐(0)