字符串专题算是搞得差不多了,来大概总结一下吧。
要掌握的算法:
1、KMP算法
作用是两个串之间的匹配,核心思想是pre[i]表示串B的最长的前缀与以i为结尾的后缀相同,每次匹配失败时,从i跳到pre[i]就可以了。
2、trie树
作用是存储许多个串,核心思想是除根节点每个点表示一个字母,从根节点到每个点的路径表示一个字符串,单词节点打上标记
3、AC自动机
作用是多个串的匹配,KMP+trie树,核心思想是fail[i]表示长度最长的某个前缀是i节点所代表的字符串的一个后缀,通过fail[i]处理出ch[x][i]表示x节点加入一个i字符后转移到的节点。注意可以结合dp来考察。
4、manacher算法
作用是处理出以每个位置为中心的最长回文串长度,核心思想是记录一个最长的延伸到的地方,利用对称的思想处理出一个当前位置的起始值,之后暴力匹配,比较神奇,时间复杂度很好证明。
5、后缀数组
作用是对单个字符串后缀排序,求两个后缀的LCP,核心思想是sa数组和height数组的求法,详见论文,不再过多赘述。
6、后缀自动机
作用是对单串建立自动机,能够给接受该串的每个子串,核心思想是每个节点代表多个字符串,其中每个节点的right集合相同,记录一个fa[i]表示最小的right集合使i的right集合是它的子集,具体还是要看论文。应用更加广泛。
7、hash
作用是判断两个字符串是否相同,核心思想是……
各大OJ的字符串题目:
1、hdu2222 Keywords Search
建出AC自动机后,在AC自动机上暴力跑,每跑到一个节点就暴力去更新所有fail节点的答案就好了,暴力可过。
2、hdu2896 病毒侵袭
同上题,建出AC自动机后,暴力跑fail指针。
3、hdu3065病毒侵袭持续中
同上题,建出AC自动机后,暴力跑fail指针。
4、poj2778 DNA Sequence
建出AC自动机后dp,dp[i][j]表示长度为i匹配到j节点的方案数,转移非常简单,非常裸的矩阵优化。
5、hdu2243 考研路茫茫――单词情结
同上,dp的时候记录加一位求和的矩阵即可。
6、hdu2825 Wireless Password
状压dp,dp[S][i][j]表示当前集合为S,匹配到第j个节点,长度为i的方案数,暴力转移。
7、hdu2296 Ring
dp,f[i][j]表示长度为i,匹配到j节点的最大分数,记录一下由哪里转移,字典序最小处理一下就可以了。
8、hdu2457 DNA repair
dp,f[i][j]表示长度为i,匹配到j节点最少改变多少个字符。
9、hdu3341 Lost's revenge
dp,懒得写了,注意要压缩状态。
10、ZOJ3494 BCD Code
数位dp+AC自动机,处理出bcd[i][j]表示i节点加上一个j转移到哪个节点,然后就是数位dp了,我是分开处理的,分别处理刚好长度为n的和长度不到n的,长度为n的分成卡住和不卡两种,长度不到n的直接转移即可,比较好理解。
11、poj1743 Musical Theme
求变化趋势肯定要先差分,然后判断是否有两段相同,那么二分答案,对height分组,那么答案的两个字符串一定在同一个组内,维护一个出现端点的最小值判断是否重叠即可。
12、poj1816 Wild Words
带有通配符的匹配,这道题比较简单,对所有串建一个trie树,之后在trie树上dfs,注意*可以停留在原地,别写成死循环了。
13、poj2752 Milking Grid
KMP,求一个最小矩阵循环后能覆盖整个矩阵,类似一维,先对每一行求一个KMP,之后求出周期的lcm即为矩阵的列数,行数同理。
14、poj2774 Long Long Message
后缀自动机,先对串A建后缀自动机,用串B在串A的自动机上匹配,记录每个位置匹配到的最长的长度,最后取最大即可。
15、poj3376 Finding Palindromes
考虑两个串可以合并的条件,一个串是另一个串翻转后的前缀,并且剩下的那一部分回文,那么我们首先用manacher处理出每个串的哪些位置可以作为结尾,然后对所有字符串建一棵trie树,用每个翻转后的字符串在trie树上匹配,途中记录下当前位置的对应的节点是否可以合并,最后在看一看该串能否作为短串进行合并。
16、poj3415 Common Substrings
后缀自动机,用原串在自动机上匹配,当当前状态匹配长度>=k的话,就记录答案,同时因为fa节点也被匹配到了,所以可以在fa节点上打上一个标记,记录被匹配到了多少次,最后一起统计。
17、poj3208 Apocalypse Someday
AC自动机上的dp,非常简单。
18、poj3261 Milk Patterns
后缀数组,二分答案后对height分组即可。
19、poj3294 Life Forms
先二分答案,对height数组分组后,处理出哪些位置可行,之后按照sa的顺序枚举就可以了。
20、poj3576 Language Recognition
先建出trie树,考虑什么时候两个节点可以合并,那就是两个节点的子树信息完全相同时,那么就进行一次子树hash就可以了。
21、poj3581 Sequence
先倒过来求出sa数组,第一次肯定交换sa[1]就好了,第二次把原来的串在后面复制一次求一遍sa,此时的sa[1]就好了,这里要特判是否后面留了后缀的位置,即sa[1]>2等等,第二次还要判断是否不在复制的串中。
22、poj3693 Maximum repetition substring
最麻烦的后缀数组,枚举长度后这个串一定经过s[1]、s[1+L]、s[1+2L]……,所以求一下这些地方的LCP,对L取模后向前平移若干个位置,若LCP变成L的整数倍,说明最佳位置在这,处理出所有位置后,按照sa枚举顺序。
23、hdu2471 History of Languages
首先把所有到达不了单词的边全部删掉,之后dfs即可。
24、hdu3901 Wildcard
带有通配符的匹配,用AC自动机来做,原谅我讲不了,还是到网上看题解吧。
25、bzoj1009 GT考试
KMP,dp[i][j]表示长度为i匹配到j的位置的方案数,暴力转移,裸的矩阵优化。
26、bzoj1030 文本生成器
补集转化,变成一个都不出现,就转化成了上面的AC自动机+dp了。
27、bzoj1031 字符加密
复制一遍后放在原字符串的后面,求一遍sa,按照sa做就好了。
28、bzoj3530 数数
数位dp+AC自动机,算了我也不想说了,很裸的。
29、bzoj3670 动物园
KMP求出pre数组,暴力的往前跳直到跳到长度小于i/2为止。
未完待续