博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 432D Prefixes and Suffixes kmp
阅读量:7104 次
发布时间:2019-06-28

本文共 2839 字,大约阅读时间需要 9 分钟。

手动转田神的大作:

 

D. Prefixes and Suffixes

time limit per test
1:second
memory limit per test:
256 megabytes
input:
standard input
output:
standard output

You have a string s = s1s2...s|s|, where |s| is the length of string s, and si its i-th character.

Let's introduce several definitions:

  • A substring s[i..j(1 ≤ i ≤ j ≤ |s|) of string s is string sisi + 1...sj.
  • The prefix of string s of length l (1 ≤ l ≤ |s|) is string s[1..l].
  • The suffix of string s of length l (1 ≤ l ≤ |s|) is string s[|s| - l + 1..|s|].

Your task is, for any prefix of string s which matches a suffix of string s, print the number of times it occurs in string s as a substring.

Input

The single line contains a sequence of characters s1s2...s|s(1 ≤ |s| ≤ 105) —  string s. The string only consists of uppercase English letters.

Output 

In the first line, print integer k (0 ≤ k ≤ |s|) — the number of prefixes that match a suffix of string s. Next print k lines, in each line print two integers lici. Numbers li ci mean that the prefix of the length li matches the suffix of length li and occurs in string s as a substring ci times. Print pairs li ci in the order of increasing li.

Sample test(s)
input
ABACABA
output
31 43 27 1
input
AAA
output
31 32 23 1
 
题目链接 :
 
题目大意 :给一个字符串,求其前缀等于后缀的子串,输出子串的长度和其在原串中出现的次数,子串长度要求曾序输出
 
题目分析 :首先得到母串的next数组,next数组的含义是next[j]的值表示str[0...j-1](我的next[0]是-1)这个子串的前后缀匹配的最长长度,如样例1
index  0  1  2  3  4  5  6  7
str    A  B  A  C  A  B  A
next   -1 0  0  1  0  1  2  3
next[6] = 2即ABACAB这个子串的前后缀最长匹配是2(AB)
由此性质我们可以发现满足条件的子串即是next[next[len。。。]]不断往前递归直到为0,因为长的可能会包含短的,我们可以递归得到re数组(re记录的就是子串出现的次数)re数组的递归式为re[ next[temp] ] += re[temp];
 
 
1 #include 
2 #include
3 int const MAX = 1e5 + 2; 4 char str[MAX]; 5 int next[MAX], re[MAX], le[MAX], sub[MAX];; 6 int len, count; 7 8 void get_next() 9 {10 int i = 0, j = -1;11 next[0] = -1;12 while(str[i] != '\0')13 {14 if(j == -1 || str[i] == str[j])15 {16 j++;17 i++;18 next[i] = j;19 }20 else21 j = next[j];22 }23 }24 25 void kmp()26 {27 get_next();28 len = strlen(str);29 memset(re,0,sizeof(re));30 for(int i = 1; i <= len; i++)31 re[i] = 1;32 int temp = len;33 for(; temp > 0; temp--)34 if(next[temp])35 re[ next[temp] ] += re[temp];36 count = 0;37 le[count] = len;38 sub[count++] = 1;39 len = next[len];40 while(len)41 {42 le[count] = len;43 sub[count++] = re[len];44 len = next[len];45 }46 }47 48 int main()49 {50 while(scanf("%s", str) != EOF)51 {52 kmp();53 printf("%d\n",count);54 for(int i = count - 1; i >= 0; i--)55 printf("%d %d\n",le[i], sub[i]);56 }57 }

 

转载于:https://www.cnblogs.com/njczy2010/p/3935698.html

你可能感兴趣的文章