CF 432D(kmp)
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.
The single line contains a sequence of characters s1s2...s|s| (1 ≤ |s| ≤ 105) — string s. The string only consists of uppercase English letters.
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 li ci. Numbers li ci mean that the prefix of the length li matches the suffix of length li and occurs in string s as a substringci times. Print pairs li ci in the order of increasing li.
ABACABA
3 1 4 3 2 7 1
AAA
3 1 3 2 23 1
/* 大致题意;给一个字符串,按长度输出和后缀完全匹配的的前缀的长度,及该前缀在整个串中出现的次数。 解法: 这题考察的是对kmp next数组的理解 */ #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <map> #include <stack> #include <set> #include <cmath> #include <vector> #include<cstdlib> #define INF 0x3f #define eps 1e-6 #pragma comment (linker,"/STACK:102400000,102400000") using namespace std; #define maxn 100005 int next_[maxn]; char str[maxn]; int ant[maxn];//记录前缀出现的次数 int len; int n; void get_next() { int i=0; int j=-1; next_[i]=j; while(i<len) { if(j==-1 || str[i]==str[j]) { ++i; ++j; next_[i]=j; } else j=next_[j]; } } void KMP() { int i=0; int j=0; memset(ant,0,sizeof(ant)); while(i<len) { if(j==-1 || str[i]==str[j]) { i++; j++; ant[j]++; } else j=next_[j]; } for(int i=len;i>=0;i--) //大前缀包含小前缀,统计每个前缀出现的个数 if(next_[i]!=-1) ant[next_[i] ]+=ant[i]; } struct node_ { int a; int b; }node[maxn]; int main() { while(~scanf("%s",str)) { len=strlen(str); get_next(); KMP(); int tt=len; int ans=0; while(tt) { node[ans].a=tt,node[ans].b=ant[tt]; tt=next_[tt]; ans++; } printf("%d\n",ans); for(int i=ans-1;i>=0;i--) { printf("%d %d\n",node[i].a,node[i].b); } } return 0; }