![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
字符串
最光阴.
这个作者很懒,什么都没留下…
展开
-
E - DNA Sequence POJ - 2778 (AC自动机+图论小知识+矩阵快速幂)
这道题目很有趣,我觉得很好玩。虽然不会做,看了题解才懂得。刚刚开始看这道题目,以为是dp,但是所求的字符长度n的大小有20亿, 就直接放弃了。然后看了题解, 看了半天才看懂。首先构造AC自动机, 这步就是套模板。对每个输入的字符串尾部进行标记就可以了。 但是千万注意一点,当前节点是否被标记,还要考虑其失配指针指向的节点。很好理解的。 比如当前输入两个串, abcd, bc。 如果直接套原创 2017-07-29 20:32:58 · 423 阅读 · 0 评论 -
回文树
点击打开链接这篇博客写的真是很好的,让我看懂了回文树。在这篇博客的基础上我再说一下我自己的理解,回文树,是一颗树(其实是两颗树),在树中每个节点都代表着不同回文串,以及会记录这种回文串的个数,由于回文串是分为长度为奇数的回文串和偶数的回文串,所以这棵树是由两个根节点构成的,一个是代表长度为-1的回文串的根节点(这里-1只是一种定义,并不存在实际的串),一个是代表长度为0的回文串的节点。然后扫描原创 2017-10-20 21:57:04 · 271 阅读 · 0 评论 -
2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛(G. Query on a string)kmp+线段树
题目大意,给予两个串,S和T, S很长,T很短(这个很重要), 有n次操作,操作分为两种形式, 一种是把S的第i个字符替换, 第二中是截取S中l到r的一段,求T在这段出现的次数。思路:先构建一个线段树,所有节点初始化为0,然后对S和T进行kmp匹配,如果T在S中出现,就把T这次出现的T【0】位置,所对应的线段树节点变为1。例如: S为‘ADADBBAD', T为’AD', 那么线段树的节点原创 2017-09-10 10:07:59 · 458 阅读 · 0 评论 -
B - Regular Number HDU - 5972 (字符串快速匹配 sao操作)
涨知识了,还有这种字符串匹配方式。用bitset() 数据结构,来记录每个合法字符出现的位置, 然后去匹配。#include #includeusing namespace std;bitset a[20];bitset ans;const int Max_N = 1e6+20;int n, x, y;char str[5*Max_N];int main(){原创 2017-09-14 22:22:53 · 423 阅读 · 0 评论 -
E - 最长双回文串 HYSBZ - 2565
思路:套用回文串的模板求出最长回文串之后, 用两个数组L与R分别存 最长回文串右边界在当前节点的最长回文串长度,以及左边界在当前节点的最长回文串长度。然后分别在扫描一下两个数组,得到回文串左右边界在当前节点的最长回文串长度。然后取最大值就好了。#include #include #include #include #include using namespace std;const原创 2017-08-14 19:05:31 · 265 阅读 · 0 评论 -
Manacher最长回文子串(模板)
该算法就是处理一个字符串中的最长回文子串,在后缀数组中看到过相对的解法,时间复杂度可以优化到o(n),但是相对代码量太大,而面对回文串算法有相对更简单的方法,可以很简单的处理出来,代码量小,时间也是o(n)。 Manacher算法是一种dp思想,很好理解,贴出代码,方便以后自己用。#include <stdio.h>#include <iostream>#include <cstring>#原创 2017-08-06 22:39:42 · 206 阅读 · 0 评论 -
E - Power Strings POJ - 2406 (后缀数组||kmp)
这个题目是后缀数组专题里面的一道题目。结果就是照着后缀数组的思路写的果然超时了。结果上网一搜才发现kmp也能做,真是太死板了,做题。 思路:对于一个串如果它是某个串的重复得到的,那么当前串的某个后缀串suff(i)与这串的公共前缀刚好就是那个后缀串suff(i),并且串长能整除i那么这个串就是长度为i的重复串。 AC代码:#include <iostream>#include <stdio.h原创 2017-08-05 22:46:09 · 456 阅读 · 0 评论 -
H - Wireless Password HDU - 2825(AC自动机+状压DP)
我对DP向来是比较抗拒的,觉得以我的智商太难理解了。近期在刷字符串处理,结果遭遇到了这道题。这个题目真的很有意思,用的还是状态压缩dp, 第一次尝试写状压dp, 发现理解了还是很好写的。 dp[i][j][k]分别表示的是当枚举到第i个字符时, 其当下处于AC自动机的的第j个节点,其包含已知的字符串是用k这个数字的集合表示的(状态压缩在k上)。 所以状态转移方程为 dp[i+1]原创 2017-07-28 14:01:34 · 364 阅读 · 0 评论 -
AC自动机入门题目(HDU - 2222 )+模板+解释
AC自动机其实就是 字典树+KMP。 最开始的时候我没有刷字典树的题目,所以不是很能理解, 但是刷完字典树之后,对AC自动机得理解就比较简单了。 AC自动机的构造中有3个需要注意的地方: 1、next[i][j] 这个next里面存的值和字典树的是几乎一样的(不过也有些不同,下面我会解释的)。存放的是当前所在第i个节点当下一个出现的字符为j的时候的节点位置。 2、fail[i] 这个和kmp中原创 2017-07-27 19:36:53 · 263 阅读 · 0 评论 -
C - Distinct Substrings SPOJ - DISUBSTR (后缀数组)
题目意思是求给定一序列中所有不同连续子序列的个数。 对于一个长度为n的序列那么其总共的连续子序列的个数是(n+1)*n/2;所以只要用总共的减去重复的就可以了。如何计算重复的?还是要用到height数组,由于字典序排好的后缀,所以如果当前相邻字符串的公共前缀长度为k的话,那么只要用总数减取k就行了,比如一个串为abcabc在字典序中,adc与adcadc是相邻的,所以就说明了有长度为3的共同部分,原创 2017-08-03 21:27:51 · 285 阅读 · 0 评论 -
A - Musical Theme POJ - 1743(后缀数组)
人生第一道后缀数组题目,值得纪念下。 题目意思很简单,就是给予一个序列,求最长不相交的相同的连续子序列的长度(这里的相同,只要是两个序列的差值相等都算相同的序列)。 后缀数组模板题目:关键在于预处理上比较难想,(表示看了题解)。对于输入的序列,构造一个新的序列,该序列的每一位的值是原始序列相邻两位的差值。也就是说如果输入序列是a[i],那么新的序列new[i] = a[i+1] - a[i];原创 2017-08-03 21:17:25 · 345 阅读 · 0 评论 -
HDU6138 F Fleet of the Eternal Throne(字典树+后缀数组+二分)
题目大意:给予n个字符串,有q次查询,对于每次查询,求出x串与y串的最长公共子串长度,该子串至少要是n个串中的一个串的前缀。首先对输入的n个串建立字典树,方便查询前缀,然后对于每次查询输入的x与y,把x串与y串取出来,两个串连接在一起,中间用个没有出现过的字符隔开,对这个串套用后缀数组模板,然后对答案二分。对于每个二分出来的mid,按照扫描一遍height数组,如果当前的height[i]原创 2017-08-17 17:44:24 · 384 阅读 · 0 评论 -
2017多校赛 1002 Rikka with String(AC自动机+状压)
这个题目和之前做的一道题目很像:类似的题目 对于题目要求枚举到2L长度的串,由于01串本身的性质我们只用枚举到L就行了,那一半是对称的。在枚举这一半时是可以随便枚举的,因为这一般确定了,那么另一半也确定了,这样2L的串一定是个01串。 然后对于输入的n个串做如下处理:对于每个输入的串讲其插入AC自动机里面,然后将每个串的反串(然后01颠倒)也插入进去。比如对于001,我们不仅要插入001,还要将原创 2017-08-08 18:11:13 · 423 阅读 · 0 评论 -
G - Maximum repetition substring POJ - 3693 (后缀数组)
又是一道后缀数组的题目,和上一道题目是类似的,不过要输字符串本身,在同等重复次数下输出,字典序最小的。 我们只需要记录下所有达到最大重复次数的,重复段的长度就可以了,然后按照sa数组排序好的字典序,扫一遍就就可以了,遇到的第一个就可以直接输出来了。#include <iostream>#include <stdio.h>#include <cstring>#include <algorith原创 2017-08-07 22:07:22 · 258 阅读 · 0 评论 -
F - Repeats SPOJ - REPEATS
这是一篇论文里面的题目,虽然看了论文里面的解法,发现对我还是比较难理解,最后思考了好久才明白这题的具体做法。 我们去枚举重复子串的长度,如果这个子串的重复长度大于等于2,那么对每个枚举的长度L来说,我们计算S[0], S[L], S[2*L], S[3*L]……,这些相邻的两个后缀,一定会有一个大于L的前缀(也有可能在当前的前面),设这个前缀为k那么长为L的串就会重复k/L+1次,同时要考虑前面有原创 2017-08-07 18:49:20 · 331 阅读 · 0 评论 -
字典树模板 HDU - 1251
字典树模板分为动态分配内存的和数组的写法。动态分配内存的在多组数据的情况下,要销毁内存,很麻烦。建议用数组的。#include <iostream>#include <stdio.h>#include <algorithm>#include <cstring>#include <queue>using namespace std;#include <cstdio>#include <c原创 2017-07-22 22:31:31 · 227 阅读 · 0 评论 -
后缀数组模板详解。
给定一个字符串S,比如它是(abcad),那么它的后缀有”abcad“ ,"bcad ", "cad", "ad", "d", ""。 讲这些后缀字符串按照字典序排序,得到的就是后缀数组。如果用普通的排序方法,排序要o(nlogn),但是每两个字符比较大小要O(n),所以是o(n × n log n)的复杂度。但是利用特殊的算法可以将其降到o(nlogn)。 该算法的思想是,先将每个后缀数原创 2017-07-30 18:16:06 · 382 阅读 · 0 评论 -
Problem I. International Collegiate Routing ContestGym - 100548I
题目意思是,说给予n个32位IP地址,每个地址的后面有一个K,每个K代表与当前所给的IP地址的前K位相同的话,就为同一IP地址,然后问你,最少再补充多少的IP地址使得能构成所有的IP地址。 思路:字典树的题目,对于每个32位的串,输入字典树中,如果当前K小于32那么就只导入到第K位,然后在当前节点做标记,建完树后,跑一遍DFS就可以了。#include #include #includ原创 2017-10-16 19:50:27 · 278 阅读 · 0 评论