【HDU 3518】Boring counting【扩展KMP】
2014-07-23 08:34
351 查看
题意:给出一个串,找出一个最长字串,不重叠的出现次数大于1次,输出这个字串的长度。
思路:我们对母串的每一个后缀都和母串做一遍扩展KMP,这样就可以知道母串和每一个后缀都求出一个最长公共字串的长度,记录ex[i][j]为母串第j个位置开始与第i个后缀所形成的最长公共前缀的长度,则记录maxid[j]表示从母串的j位开始,最长出现次数大于1次且不重叠的字串长度。可以知道maxid[j] = max(maxid[j], min(i-j, ex[i]][j]));
每一个maxid[j]都可以产生maxid[j]个答案,接下来就是对于答案判重的情况。我们可以用字典树判重,每一个maxid[j]所代表的字串一次跑一下字典树,最后字典树的节点个数就是所求的答案。
思路:我们对母串的每一个后缀都和母串做一遍扩展KMP,这样就可以知道母串和每一个后缀都求出一个最长公共字串的长度,记录ex[i][j]为母串第j个位置开始与第i个后缀所形成的最长公共前缀的长度,则记录maxid[j]表示从母串的j位开始,最长出现次数大于1次且不重叠的字串长度。可以知道maxid[j] = max(maxid[j], min(i-j, ex[i]][j]));
每一个maxid[j]都可以产生maxid[j]个答案,接下来就是对于答案判重的情况。我们可以用字典树判重,每一个maxid[j]所代表的字串一次跑一下字典树,最后字典树的节点个数就是所求的答案。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 1010 char s , hz ; void exkmp(char *s1, char *s2, int *next, int *ex) { int i, j, p; for (i = 0,j = 0,p = -1;s1[i] != '\0';i++,j++,p--) { if (p == -1) { j = 0; do p++; while (s1[i+p] != '\0' && s1[i+p] == s2[j+p]); ex[i] = p; } else if (next[j] < p) ex[i] = next[j]; else if (next[j] > p) ex[i] = p; else { j = 0; while (s1[i+p] != '\0' && s1[i+p] == s2[j+p]) p++; ex[i] = p; } } ex[i] = 0; } int next ,extand , mxid ; struct Tr{ Tr *c[26]; Tr() { for (int i = 0;i < 26;i++) c[i] = NULL; } }*root; int cnt; void ins(int st, int len) { int i, j; Tr *p = root; for (i = 0;i < len;i++) { j = s[i+st]-'a'; if (p->c[j] == NULL) { p->c[j] = new Tr(); cnt++; } p = p->c[j]; } } int main() { int len, i, j; while (~scanf("%s", s), s[0] != '#') { len = strlen(s); memset(mxid, 0, sizeof(mxid)); for (i = 1;i < len;i++) { exkmp(s+i+1, s+i, next, next+1); exkmp(s, s+i, next, extand); for (j = 0;j < i;j++) { mxid[j] = max(mxid[j], min(i-j, extand[j])); } } root = new Tr(); cnt = 0; for (i = 0;i < len;i++) { ins(i, mxid[i]); } printf("%d\n", cnt); } }
相关文章推荐
- [HDOJ 3518][Vjudge 10885] Boring counting [扩展kmp+Hash]
- HDU 3518 Boring counting
- hdu 4300 Clairewd’s message 扩展kmp
- hdu 4300 Clairewd’s message(扩展KMP)
- HDU 4333 Revolving Digits2012多校联赛第四场C题(扩展KMP+KMP)
- HDU 3518 Boring counting(后缀数组 所有不重叠字串出现两次以上的次数)
- 杭电hdu 3518 boring counting 后缀数组学习
- HDU 3613Best Reward(扩展KMP解法)
- HDU 3518 Boring counting(后缀数组)
- hdu 3068(扩展KMP)
- Hdu 3518 Boring counting (出现2次及以上且不重叠的子串的个数)
- hdu 3518 Boring counting
- hdu - 4333 - Revolving Digits - 扩展kmp
- hdu 3068 最长回文 (Manacher O(n) ) (扩展KMP和后缀数组也都可以做 O(nlogn))
- hdu 3518 Boring counting(后缀数组+height分组)
- hdu 4300 Clairewd’s message (扩展KMP)
- HDU 3518 Boring counting(后缀数组)
- HDU 4333 Revolving Digits (扩展KMP)
- hdu4333之扩展KMP
- hdu 4333 扩展kmp