随笔分类 - 字符串
摘要:一个比较暴力的解法. 先对所有串建出广义后缀自动机提取出后缀树然后按照询问的右端点离线. 考虑插入第 $i$ 个串,那么会被 $i$ 及 $i$ 的祖先遍历到的点的表示范围会从 $[l,r] \rightarrow [l,r+1]$. 未被遍历到的点的表示范围出现了一个“断点”,则表示范围就是 $i
阅读全文
摘要:比较好的一道后缀自动机题. 先枚举必选的前缀 $[1,k]$ 然后加上 $[k+1,n]$ 中本质不同子串个数. 但是这样的话会算重. 考虑哪些地方算多了: 假设 $i-1$ 的前缀为 $pre[i-1]$,然后当前的前缀为 $pre[i-1]+x$. 那么当前肯定会枚举到 $pre[i-1]+(x
阅读全文
摘要:线段树加 hash 判重模板题. hash 的话必须要用双 base 哈希,否则会 WA. 然后这道题中最好不要用自然溢出,感觉比取模还要慢一些. 由于读入量巨大,必须要开读入优化才能过. 哈希的方式就是对于每个数维护 $\sum base^{num[i]}$,由于值域不大,提前预处理出来 base
阅读全文
摘要:正常来说,单次操作的复杂度是 $O(k^2)$,然后整体复杂度是 $O(nk^2)$. 但是我们发现每次合并两个蚯蚓的复杂度的极限是 $O( min(size_{min},50) \times 50)$. 然后根据启发式合并的复杂度分析,即使要求遍历完 $size_{min}$,复杂度最高也就是 $
阅读全文
摘要:怎么想都没想出来 $\log n$ 做法,那么这道题基本就是根号分治了. 题目描述中保证 $\sum k \leqslant 10^5$,然后 $k$ 在每次询问中又是相同的,那么就考虑对 $k$ 根号分治. 先对 $s$ 建立后缀自动机,然后把倍增数组求出来. 我们设块的大小为 $B$,那么当 $
阅读全文
摘要:并不难的一道字符串题. 显然后缀自动机上进行字典树的启发式合并. 但是一定注意,题中要求的是两个后缀的 LCP 而不是两个前缀的 LCP. 所以在构建后缀自动机的时候要从后向前构建. 刚开始从前向后构建 WA 了半天. 然后进行启发式合并的时候可以对每个节点维护一个 id[x],如果儿子的大小大于点
阅读全文
摘要:问题可以转化为:$A$ 与 $B$ 所有前缀一一配对,LCP 之和最大是多少. 构建后缀树,然后对于点 $x$,若 LCP 为 $x$ 则贡献就是 $x$ 子树中 $A$ 点和 $B$ 点较小数量. 我们发现如果要求和最大,就贪心匹配. 由于后缀树中点 $x$ 的长度为 mx[x] ~ mx[pre
阅读全文
摘要:不难的一道字符串题. 建立 $T$ 的 SAM,然后根据 $S$ 中的询问按照右端点离线,依次在 $T$ 的 SAM 上匹配. 查询的时候分两种情况讨论一下,用线段树维护就行了. code: #include <cstdio> #include <cstring> #include <algorit
阅读全文
摘要:显然取对数,然后二分答案进行 01 分数规划. 设 $f[i][j]$ 表示在 AC 自动机上的点 $i$ ,匹配到了 $j$ 位的最大价值. 转移的时候判断一下当前是点还是数字,然后在 AC 自动机上的终止节点上算一下贡献就行. 构建 AC 自动机的时候要注意:点 $i$ 的价值是 val[i]+
阅读全文
摘要:后缀自动机的做法很显然:建出后缀树,线段树合并,然后倍增的时候更新答案就行. 后缀数组的做法也挺显然:二分答案,然后用主席树判定一下 $[a,b-mid+1]$ 是否有值即可. code: #include <bits/stdc++.h> #define N 200006 #define lson
阅读全文
摘要:嘴巴上把这道题切了,但是写代码的时候好多细节都需要注意. 1. 大概可以猜到能表示出的数字比多,但是这一步要用 BFS+hash 才行,因为用 DP 求解的话会有好多无用状态. 2. 做动态规划的时候如果对与状态有限制条件的话比较好写的方法是由合法状态去转移下一步,而不是枚举当前状态去找上一步的状态
阅读全文
摘要:这道题是 KMP 来转移子串中的相对排名. 然后查询排名的话需要用到树状数组. 如果跳 fail 指针的话要把没用元素全部删掉. code: #include <bits/stdc++.h> #define N 1005000 #define setI(s) freopen(s".in","r",s
阅读全文
摘要:KMP 的 fail 指针指向的位置是具有循环节性质的. code: #include <bits/stdc++.h> #define ll long long #define N 1000020 #define setIO(s) freopen(s".in","r",stdin) using na
阅读全文
摘要:暴力的做法是求出 $next$ 数组后倍增求解答案. 但实际上不用这么麻烦,再做一次类似于 KMP 的东西就可以了. code: #include <bits/stdc++.h> #define N 1000006 #define ll long long #define setI(s) freop
阅读全文
摘要:新学一发扩展 KMP. 和 KMP 一样,都是均摊复杂度 $O(n)$. code: #include <bits/stdc++.h> #define N 20000007 #define ll long long #define setI(s) freopen(s".in","r",stdin)
阅读全文
摘要:好神仙的一道字符串题! 由于后缀自动机+线段树合并的题做多了,看到复杂字符串的时候直接往 right 集合和后缀树那方面想了. 所以就没想出来 QAQ.... 这道题还是要从序列上来思考. 我们发现最优解一定可以表示成一个长度依次为 $1$ ~ $ans$ 字符串集合. 令 $dp[i]$ 表示以
阅读全文
摘要:将问题转化为统计以 $i$ 结尾的 $AA$ 串个数. 我们将后缀树建出来,然后按照启发式合并的方式每次合并两个 $endpos$ 集合. 那么就有:$[x-mx,x-1] \rightarrow x$ 与 $x \rightarrow [x+1,x+mx]$ 的贡献. 统计第一种贡献的话在线段树上
阅读全文
摘要:用 trie 搜索一下就好了. code: #include <bits/stdc++.h> #define N 10008 #define setIO(s) freopen(s".in","r",stdin) using namespace std; char S[24]; int trie[N*
阅读全文
摘要:第一次写这个题是好长时间以前了,然后没调出来. 本来以为是思路错了,结果今天看题解发现思路没错,但是好多代码细节需要注意. code: #include <cstdio> #include <vector> #include <map> #include <cstring> #include <al
阅读全文
摘要:Description Viruses are usually bad for your health. How about fighting them with... other viruses? In this problem, you need to find out how to synth
阅读全文

浙公网安备 33010602011771号