随笔分类 - ACM_字符串
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题意:给两个串S和P,求S串中存在多少个与P串的大小关系一样的串。 因为数字的范围是1 3 #include 4 #include 5 //#include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include 16 #include 17 #include 18 ...
阅读全文
摘要:题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=26580 题意:给一个模式串,然后m个匹配串,要求删掉匹配串中的所有存在的模式串,使得余下的串中没有模式串。 数据很大,需要O(N)的算法。。。 首先kmp求出模式串的next数组,然后就是kmp匹配了。 但是我们要注意到是要删尽,如BBUGUG,这个样例是删没了的,因此在kmp匹配的时候,对于每个字符 i,我们需要维护两个值 l 和 r,分别表示 i 的左边的有效字符串的下标和右边有效字符串的下标。同时还要维护一个cur[i]数组,表示位置为 i 的字符的next值。然后如...
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 后缀数组模板题,求出Height数组后,对Height做RMQ,然后直接统计就可以了。。。 1 //STATUS:C++_AC_828MS_11284KB 2 #include 3 #include 4 #include 5 //#include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #incl...
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 题意:给一个字符串,询问某字串的不同字串的个数。 可以用后缀数组来解决,复杂度O(n)。先求出倍增算法求出sa数组,然后DP求出Height数组,对于每个询问,重构sa数组,这里重构可以利用整个串的sa数组来得到,但是这里截取的字串,可能顺序会变化,看一个例子:cacbe 排序为:acbe,be,cacbe,cbe,e 得到字串[0,2]的排序是:acbe(1),cacbe(0),cbe(2) 但cac的实际排序是:ac(1),c(2),cac(0) 后缀0和2的顺序反了,因此...
阅读全文
摘要:转自:https://www.byvoid.com/zht/blog/string-hash-compare 常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎不可能找到碰撞。 常用字符串哈希函数有BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。对于以上几种哈希函数,我对其进行了一个小小的评测。Hash函数数据1数据2数据3数据4数据1得分数据2得分数据3得...
阅读全文
摘要:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4552 题意:求字符串中所有前缀的出现的次数。 比赛的时候使用后缀数组写的,后来比完后发现KMP+DP完全可以搞,当时沙茶了- -。然后更神奇的是,这题数据太弱了,暴力完全够了,对于随机数据,基本上就是O(n)的算法,当然如果完全每个字符都一样,那么就是O( n^2 )了。然后...我就缩代码到151B,刷到status第一了~后缀数组: 1 //STATUS:C++_AC_78MS_3204KB 2 #include <functional> 3 #include <algori
阅读全文
摘要:2008年OI集训论文上有介绍<对块状链表的一点研究>,其主要是结合了链表和数组各自的优点,链表中的节点指向每个数据块,即数组,并且记录数据的个数,然后分块查找和差入。在g++头文件中,<ext/rope>中有成型的块状链表,在using namespace __gnu_cxx;空间中,其操作十分方便。 基本操作: rope list; list.insert(sta,string); list.erase(sta,end); list.copy(sta,len,string); 算法复杂度n*(n^0.5),可以在很短的时间内实现快速的插入、删除和查找字符串的效果,简
阅读全文
摘要:题目链接:http://poj.org/problem?id=1204 从字符矩阵的边缘字符扩展匹配分别记录最小值。 1 //STATUS:C++_AC_704MS_12432KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector>
阅读全文
摘要:题目链接:http://poj.org/problem?id=3691 首先庆祝1A。 如果是单串的匹配,那么状态转移方程就是f[i][j],表示匹配串的前 i 位最近9个数字的状态是 j 的最小改动,每个状态用状态压缩表示下就可以了。复杂度是指数级,对于较小的字符串还是可以接受的。但是这个有很多不必要的情况,因为很多转移都可以归纳到一起,即修改或者不修改,因此把方程改为表示匹配串的第 i 为模板串的第 j 个节点时的最优解,那么对于每个节点就只有4种转移状态了,即一个单串的DFA。同样,我们对于多个串建立一个AC自动机就可以了,转移方程:f[i][j]=Min{ f[i][j] ,...
阅读全文
摘要:题目链接:http://poj.org/problem?id=2778 [摘自Matrix67] 题目大意是,检测所有可能的n位DNA串有多少个DNA串中不含有指定的病毒片段。合法的DNA只能由ACTG四个字符构成。题目将给出10个以内的病毒片段,每个片段长度不超过10。数据规模n<=2 000 000 000。 下面的讲解中我们以ATC,AAA,GGC,CT这四个病毒片段为例,说明怎样像上面的题一样通过构图将问题转化为例题8。我们找出所有病毒片段的前缀,把n位DNA分为以下7类:以AT结尾、以AA结尾、以GG结尾、以?A结尾、以?G结尾、以?C结尾和以??结尾。其中问号表示“其它情况.
阅读全文
摘要:题目链接:http://poj.org/problem?id=3294 多个串中,出现次数为k次的最长公共子串的个数,并且输出。 一般的算法就是后缀数组加二分,复杂度O(n*logn)。其实也可以和POJ3415一样维护一个栈,思想都是差不多的,维护一个单调递增的栈,每到一个height[i]时,先保证栈单调递增并且统计个数sum,然后height[i]再与当前最优值比较,如果大于最优值,那么看sum是否大于k,如果大于则更新最优值。平均复杂度O(n)。 二分代码: 1 //STATUS:C++_AC_375MS_4328KB 2 #include<stdio.h> 3 #in..
阅读全文
摘要:题目链接:http://poj.org/problem?id=3415 求两个串的长度不小于K的公共字串的个数。 利用height[]来维护一个单调递增的栈,即栈保存的是满足要求的heigiht数组的最小值,附加维护栈中相邻两个元素之间的个数。 1 //STATUS:C++_AC_813MS_6532KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<
阅读全文
摘要:题目链接:http://poj.org/problem?id=2774 两个字符串的最长公共字串。 求出height数组后直接二分答案就可以了,或者线性扫描一遍。 1 //STATUS:C++_AC_594MS_4800KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9
阅读全文
摘要:题目链接:http://poj.org/problem?id=3693 求字符串的重复次数最多的且字典序最小的字串。 很不错的题目。罗穗骞大牛论文的模板题,摘了Neo / Add ~0U>>1大牛的详细题解,如下: 首先求第一问最大重复数。从N的范围来看O(N^2)虽不靠谱,但是起码能带来些有用的启示。方法有二,一是枚举开头位置求重复长度;二是枚举重复长度求开头位置。第一种方法求最大重复数的方法MS也只有枚举重复长度然后去判……所以说我们从第二个方法入手。O(N^2)的方法是再枚举开头位置。我们来考虑一下能不能少枚举一些开头位置——更确切地说,能不能只枚举一些特殊位置,设当前枚举的
阅读全文
摘要:题目链接:http://poj.org/problem?id=3261 求可重叠的至少出现K次的最长公共前缀。 先用后缀数组求出height数组,然后二分答案。 1 //STATUS:C++_AC_47MS_720KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #in
阅读全文
摘要:题目链接:http://poj.org/problem?id=1743 题意:给一些数字串,当做韵律,相同的韵律必须满足: 1,最少5个数字长; 2,重复出现的时候,必须相对差值一样,比如{ 1 ,2, 3, 22, 10, 11, 12 },1,2,3与10 11 12是一样的韵律。 3,韵律不可重叠。 先用后缀数组处理,然后对height数组二分答案就好了。 1 //STATUS:C++_AC_266MS_724KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #incl
阅读全文
摘要:关于后缀数组的资料,可以看NOI2009国家集训队论文罗穗骞 的<后缀数组——处理字符串的有力工具>。/* suffix array 倍增算法 O(n*lgn) build_sa( ,n+1, ) 注意n+1 getHeight( , n) n = 8 ; num[] = { 1, 1, 2, 1, 1, 1, 1, 2, $ }. 注意num数组最后一位值为0,其它位须大于0! rank[] = { 4, 6, 8, 1, 2, 3, 5, 7, 0 }. (rank[0~n-1]为有效值) sa[] = { 8, ...
阅读全文
摘要:题目链接:http://poj.org/problem?id=3461 典型的KMP模板题,直接匹配个数即可。 1 //STATUS:C++_AC_94MS_1240KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector>10 #i
阅读全文
摘要:题目链接:http://poj.org/problem?id=3630 建立一个Trie树查找就可以了,但是这里动态建立Trie居然会超时,静态化居然可以秒,太不厚道了= = 当然还可以用qsort秒过,依次比较。。。 1 //STATUS:C++_AC_110MS_2568KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8
阅读全文
摘要:题目链接:http://poj.org/problem?id=3974 Manacher算法效率真不错,用后缀数组A的都沙茶了。。 1 //STATUS:C++_AC_235MS_10904KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vec
阅读全文