
字符串算法
文章平均质量分 55
DP,匹配,后缀数组等
SHOHOKUKU
这个作者很懒,什么都没留下…
展开
-
Codeforces 1828E Manacher + DP
表示为唯一的分割形式。Manacher 求解以各个位置为中心的回文串最长长度,用一个栈维护有序的回文串中心位置,不断弹出无法覆盖当前位置的元素,则可以得到。中以各个位置为左边界的最短回文串。DP 求解以各个位置为边界的答案即可。观察到对于任一个 “beautiful string”对于此类后推形式的 DP,倒序递推较为方便,可以以。为左边界的最短回文串,将。原创 2023-07-01 17:05:35 · 404 阅读 · 0 评论 -
Codeforces 1535F 字符串 + 倍增 + BIT
若字符串 $a,b$ 的字符多重集合不相等,则 $f(a,b) = 1337$。反之,将 $a,b$ 整个串做排序必然相等,则 $f(a,b)\leq 2$。此时只用考虑 $f(a,b)=1$ 的情况。若仅对 $a$ 进行一次子串 $[l,r)$ 排序使 $a = b$,则字典序意义下 $a>b$;且 $a,b$ 在 $l$ 左侧的前缀与 $r$ 右侧的后缀相等,则字典序意义下 $a,b$ 的反串 $a^{\prime},b^{\prime}$ 满足 $a^{\prime}原创 2022-10-27 20:37:53 · 476 阅读 · 0 评论 -
P2178 [NOI2015] 后缀数组 + 并查集
题意传送门 P2178 [NOI2015] 品酒大会题解构造后缀数组,按照 lcplcplcp 从大到小依次处理,同时使用并查集维护连通分量中的最大、最小值与后缀数量。此时可以统计出 lcp=hlcp = hlcp=h 时的方案数与美味度最大值。根据相似度的定义,最后求一遍后缀即可。总时间复杂度 O(nlog2n)O(n\log^2 n)O(nlog2n)。#include <bits/stdc++.h>using namespace std;constexpr int MAXN原创 2022-04-15 10:54:00 · 153 阅读 · 0 评论 -
Codeforces 291E KMP + DFS
题意传送门 Codeforces 291E Tree-String Problem题解KMPKMPKMP 构建自动机。将 sis_isi 看作 iii 的点权,DFSDFSDFS 统计即可。总时间复杂度 O(∣t∣+∑∣si∣)O(\lvert t\rvert+\sum\lvert s_i\rvert)O(∣t∣+∑∣si∣)。#include <bits/stdc++.h>using namespace std;#define rep(i, l, r) for (int i =原创 2021-12-15 17:58:27 · 944 阅读 · 0 评论 -
Codeforces 808G KMP + DP
题意传送门 Codeforces 808G Anthem of Berland题解设 dp[i+1][j]dp[i+1][j]dp[i+1][j] 代表以 iii 为结尾的 sss 前缀与 ttt 的最长匹配长度为 jjj 时,模式串 ttt 在 sss 前缀中出现的最多次数。KMPKMPKMP 建自动机求解即可。总时间复杂度 O(26×∣s∣×∣t∣)O(26\times\lvert s\rvert\times\lvert t\rvert)O(26×∣s∣×∣t∣)#include <bit原创 2021-12-14 18:31:47 · 413 阅读 · 0 评论 -
P3193 [HNOI2008] KMP + 矩阵快速幂
题解传送门 P3193 [HNOI2008]GT考试题解以准考证号后缀与不吉利数字的最长匹配长度为状态,KMPKMPKMP 预处理处状态转移矩阵,进行矩阵快速幂即可。总时间复杂度为 O(M3logN)O(M^3\log N)O(M3logN)。#include <bits/stdc++.h>using namespace std;#define rep(i, l, r) for (int i = l, _ = r; i < _; ++i)const int MAXN = 2原创 2021-11-27 18:42:56 · 214 阅读 · 0 评论 -
P5319 [BJOI2019] 二分 + AC 自动机 + DP
题意传送门 P5319 [BJOI2019]奥术神杖题解求 ∏Vic\sqrt[c]{\prod V_i}c∏Vi 的最大值。若直接计算,需要上高精度;暴力枚举更换的宝石,总时间复杂度 O(10N)O(10^N)O(10N)。将答案取对数进行考虑 ∑lnVic\frac{\sum \ln V_i}{c}c∑lnVi 则转化为 0/10/10/1 分数规划问题。二分答案的对数值,判定是否存在满足下式的方案 ∑(lnVi−x)≥0\sum (\ln V_i-x)\geq 0∑(lnVi−x)原创 2021-03-26 12:29:17 · 89 阅读 · 0 评论 -
P4398 [JSOI2008] 二维 Hash
题意传送门 P4398 [JSOI2008]Blue Mary的战役地图题解从大到小枚举正方形的边长,使用二维 HashHashHash 处理两张地图的各个正方形,最后对一张地图的 HashHashHash 值排序,枚举另一张地图 HashHashHash 值并二分求解两张地图是否存在相同正方形。总时间复杂度 O(N3logN)O(N^3\log N)O(N3logN)。#include <bits/stdc++.h>using namespace std;typedef unsi原创 2021-03-04 10:21:57 · 77 阅读 · 1 评论 -
P3501 [POI2010] 二分 + Hash
题意传送门 P3501 [POI2010]ANT-Antisymmetry题解将字符串 SSS 各位反转得到 rSrSrS,可以观察到满足条件的子串满足类似回文串的性质。假设长为 xxx 的子串对称中心左边第一个字符为 iii,则有 S[i−x+1,i]=rS[i+1,i+x]S[i-x+1,i]=rS[i+1,i+x]S[i−x+1,i]=rS[i+1,i+x]。HashHashHash 预处理 S,rSS,rSS,rS,枚举对称中心,二分满足条件的子串的最长长度,同时更新答案。#include原创 2021-03-03 22:10:53 · 117 阅读 · 1 评论 -
AcWing160 二分 + Hash / KMP
题意传送门 AcWing 160 匹配统计题解很容易想到字符串 HashHashHash,枚举后缀,二分对应的最长匹配前缀。时间复杂度 O(Mlog(min(N,M)))O(M\log(\min(N,M)))O(Mlog(min(N,M)))。#include <bits/stdc++.h>using namespace std;const int maxn = 200005;char A[maxn], B[maxn];int N, M, Q, nxt[maxn], cnt[原创 2021-02-15 21:11:07 · 128 阅读 · 0 评论 -
POJ 2185 Hash + KMP
题意传送门 POJ 2185 Milking Grid题解使用 KMPKMPKMP 可以方便地求解最小循环元长度。简单地证明充分性,匹配的后缀与前缀是按照 i−nxt[i]i-nxt[i]i−nxt[i] ,即循环元长度间隔错位对齐,若 (i−nxt[i])∣i(i-nxt[i])\mid i(i−nxt[i])∣i,则字符串由整数倍的循环元构成;当 (i−nxt[i])∤i(i-nxt[i])\nmid i(i−nxt[i])∤i 时,从字符串末尾以 i−nxt[i]i-nxt[i]i−nxt[i]原创 2021-02-09 19:24:31 · 138 阅读 · 0 评论 -
AcWing 156 二维 Hash
题意传送门 AcWing 156 Matrix题解对 M×MM\times MM×M 矩阵中的 A×BA\times BA×B 子矩阵进行二维哈希,具体思路为先按行求解宽为 BBB 的子区间的哈希值,再按列求解高为 AAA 的子矩阵哈希值。使用 setsetset 维护出现的子矩阵,总时间复杂度 O((NM+Q)log(NM))O((NM+ Q)\log (NM))O((NM+Q)log(NM))。#include <bits/stdc++.h>using namespace std原创 2021-02-08 22:42:38 · 125 阅读 · 0 评论 -
HDU 3374 最小 / 大表示法
题意传送门 HDU 3374 String Problem题解求字符串中字典序最小与最大的循环同构串,并求解对应的起始字符在原字符串中出现的位置最早的一个,以及这个循环同构串出现的次数。最小/大表示法字符串字典序最小/大的循环同构串称为字符串的最小/大表示。设字符串 SSS 长度为 nnn,最小/大表示法的可以 O(n)O(n)O(n) 求解,区别只在于字典序的判断。以最小表示法的求解为例,将原串 SSS 复制一份接在其结尾,得到的字符串记为 SSSSSS,则有 SS[i,i+n),i∈[0,n)原创 2021-02-05 21:50:58 · 149 阅读 · 0 评论 -
POJ 3349 Hash + 最小表示法
大致题意有 n 朵雪花,输入 6 条冰晶的长度 [0, 10000000),输入序列可能从任一条冰晶开始,顺时针或逆时针顺序输入。求是否各个雪花都不一样。0 < n ≤ 100000每朵雪花有 12 种排序,直接两两比较复杂度会爆。Hash 可以在发生冲突时才进行判断,要保证同构性的序列 Hash 值一致。因为是偶数长度序列,可以奇数位、偶数位分别相加再异或处理。#include &l...原创 2020-03-07 11:34:01 · 217 阅读 · 0 评论 -
POJ 1961 KMP
题意传送门 POJ 1961 Period题解若字符串长度大于 111 的前缀存在最小循环元,求其最大循环次数。S[1…i]S[1\dots i]S[1…i] 具有长度为 len<ilen<ilen<i 的循环元的充要条件是 lenlenlen 能整除 iii 并且 S[len+1…i]=S[1…i−len]S[len+1\dots i]=S[1\dots i-len]S[len+1…i]=S[1…i−len],此时 i−leni-leni−len 是 KMPKMPKMP 算法的原创 2021-01-30 13:58:46 · 84 阅读 · 0 评论 -
Codeforces 452E 后缀数组 + 并查集
题意传送门 Codeforces 452E. Three strings题解将子串看做后缀的前缀,那么使用两个互不相同且非小写字母的字符将 333 个字符串拼接起来,求解后缀数组以及高度数组。由于后缀数组的有序性,故最长相同前缀不小于某个长度 hhh 的后缀集合在后缀数组中处于连续的位置,且对应位置的高度数组的值不小于 hhh。那么可以使用并查集维护这样连续的位置,从高度数组的最大值(333 个字符串的最长长度)开始处理,使用相邻 sa[i],sa[i+1]sa[i],sa[i+1]sa[i],sa原创 2020-11-25 21:26:50 · 182 阅读 · 0 评论 -
POJ 3415 后缀数组 + 单调栈 / 并查集
题意传送门 POJ 3415题解子串是原串中连续的一段,也可以定义为前缀的后缀或后缀的前缀。统计分别属于 A,BA,BA,B 的不小于 KKK 的子串个数,那么将 A,BA,BA,B 用一个不属于这两个串的字符拼接起来(避免拼接位置对结果产生影响),构造后缀数组以及高度数组(lcp[i]lcp[i]lcp[i] 为 a[i],sa[i+1]a[i],sa[i+1]a[i],sa[i+1] 的最长公共前缀)。设任意两个后缀在后缀数组中的索引分别为 i,j(i<j)i,j(i<j)i,j原创 2020-11-24 00:07:26 · 369 阅读 · 0 评论 -
POJ 1509 后缀数组
题意传送门 POJ 1509题解求长度为 nnn 的字符串构成的环任一位置拆分成的 nnn 条链中,字典序最小的,若有多个答案,则返回拆开位置索引最小的。将原串复制一份连接到自身后面,求后缀数组,实现上使用基于倍增的方法。答案为满足长度大于等于 nnn 的后缀的长度为 nnn 的前缀。为了满足拆开位置索引最小的要求,有两种思路:求解后缀数组时,将超出后缀长度的部分赋最大的权值,此时保证按字典序排序时,较短串为较长串前缀时,较短串字典序比较长串更大;或者直接在复制拼接的字符串后面添加一个字典序最大的字原创 2020-11-21 20:47:09 · 149 阅读 · 0 评论 -
P4584 [FJOI2015] 序列自动机 + AC 自动机 + SPFA
题意传送门 P4584 [FJOI2015]带子串包含约束LCS问题题解分别对 X,YX,YX,Y 建序列自动机,那么可以从根节点搜索以遍历所有的公共子序列。对约束集子串建 ACACAC 自动机,搜索的同时更新子序列后缀状态。对约束集子串进行状态压缩,在 ACACAC 自动机 BFSBFSBFS 计算失配指针时,将各个节点对应的后缀状态记录所有的等于约束子集的后缀。最后 SPFASPFASPFA 求解最长子序列。#include <algorithm>#include <cmat原创 2020-10-19 11:49:30 · 192 阅读 · 0 评论 -
Codeforces 1295C 序列自动机 + 贪心
题意传送门 Codeforces 1295C Obtain The String题解建立 SSS 的序列自动机,每一次贪心的选择 SSS 中可匹配 TTT 剩余字符的最长子序列。若最优解出现某次选择中未取 SSS 满足条件的最长子序列,那么此次取最长子序列答案不会增大。#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>using namespace st原创 2020-10-18 22:38:26 · 173 阅读 · 0 评论 -
P4608 [FJOI2016] 序列自动机
题意传送门 P4608 [FJOI2016]所有公共子序列问题题解序列自动机,原理即记录序列各个位置对应的每一个字符集元素的下一个出现的位置,则从根节点 DFSDFSDFS 即可遍历所有子序列。对于公共子序列问题,将序列 X,YX, YX,Y 处理为序列自动机,从根节点沿相同路径 DFSDFSDFS,则遍历的所有路径对应了所有的公共子序列。#include <algorithm>#include <cmath>#include <cstdio>#includ原创 2020-10-18 21:28:04 · 200 阅读 · 0 评论 -
AOJ 1312 二维 Hash
题意传送门 AOJ 1312题解使用二维滚动哈希计算得到图片中所有 p×pp\times pp×p 的子阵哈希值,以及旋转、镜面翻转共 2×42\times 42×4 种模式子阵的哈希值,枚举各位置进行匹配即可。#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>using namespace std;#define inf 0x3f3f3f3f#de原创 2020-09-19 16:35:58 · 138 阅读 · 0 评论 -
AOJ 2212 AC 自动机 + BFS
题意传送门 AOJ 2212题解ACACAC 自动机预处理出迷宫路线对应的字符串的后缀模式。以后缀模式为状态,若状态对应节点或其失配指针指向的节点为禁止模式串,则此状态包含禁止模式。以坐标位置、路线后缀状态为总的状态,BFSBFSBFS 求最短路即可。#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <queue>usi原创 2020-09-18 23:07:59 · 167 阅读 · 0 评论 -
HDU 2457 AC 自动机 + DP
题意传送门 HDU 2457题解初始化 ACACAC 自动机,将 TrieTrieTrie 上节点看做字符串后缀的不同模式(或者状态)。若一个模式存在目标基因,那么这个节点或其失配节点(最长前缀)对应的字符串是目标基因。计算失配指针的时候,处理了各节点的所有状态转移(即在字符串结尾添加 A,C,G,TA,C,G,TA,C,G,T 其中一个字符),同时标记各状态是否存在目标基因即可。dp[i+1][j]dp[i+1][j]dp[i+1][j] 代表字符串在区间 [0,i][0,i][0,i] 且后缀模原创 2020-09-14 22:43:59 · 177 阅读 · 0 评论 -
POJ 2778 AC 自动机 + 矩阵快速幂
题意传送门 POJ 2778题解初始化 ACACAC 自动机,将 TrieTrieTrie 树上节点看做字符串的状态(字符串后缀模式),显然各节点有 A,C,G,TA,C,G,TA,C,G,T 四种状态可以转移(对应了 DNADNADNA 序列在末尾添加一个字符),且转移后节点依然在 TrieTrieTrie 树上。判断一个状态是否具有疾病基因,只要判断对应节点或节点的失配节点(即其后缀)是否对应了疾病基因即可。构造矩阵,维度为 TrieTrieTrie 节点数,即字符串可能的状态数,mat[i]原创 2020-09-14 21:30:28 · 87 阅读 · 0 评论 -
HDU 2896 AC 自动机
题意传送门 HDU 2896题解ACACAC 自动机的节点记录特征码的编号,查询时统计即可,注意字符集为 ASCⅡ。#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define maxn 505#define base 128#define maxl 1000原创 2020-09-14 19:28:55 · 115 阅读 · 0 评论 -
HDU 2222 AC 自动机
题意传送门 HDU 2222题解多模式匹配,裸的 ACACAC 自动机。#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>#include <queue>using namespace std;#define maxn 10000#define maxl 1000005struct node{ int cnt, a[26];原创 2020-09-14 18:22:41 · 149 阅读 · 0 评论 -
POJ 2406 KMP
题意传送门 POJ 2406题解KMPKMPKMP 算法中 b[i]b[i]b[i] 代表字符串区间 [0,i−1][0,i-1][0,i−1] 的最长且相等的前缀与后缀长度。设字符串长度为 lenlenlen,那么循环节的长度为 len−b[len]len-b[len]len−b[len];若不满足 len%(len−b[len])==0len\%(len-b[len])==0len%(len−b[len])==0 则 n=1n=1n=1。#include <algorithm>#i原创 2020-08-17 20:42:28 · 138 阅读 · 0 评论 -
POJ 3080 枚举 + KMP
题意传送门 POJ 3080题解长度从大至小枚举子串,使用 KMPKMPKMP 算法匹配各序列即可。答案为最长子串,若存在相同长度子串,输出字典序最小的。#include <algorithm>#include <cmath>#include <cstdio>#include <cstring>using namespace std;#define maxm 12#define maxs 65int n, m, b[maxs];char原创 2020-08-14 21:36:32 · 148 阅读 · 0 评论