Description
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 lici mean that the prefix of the length li matches the suffix of length li and occurs in string s as a substring citimes. Print pairs liciin the order of increasingli.
Sample Input
ABACABA
3
1 4
3 2
7 1
AAA
3
1 3
2 2
3 1
前缀和后缀,当然是kmp算法的应用,我竟然想了好久
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; char p[100000+10]; int f[100000+10],a[100000+10],dp[100000+10]; void getf() { int m=strlen(p); f[0]=f[1]=0; for (int i=1;i<m;i++) { int j=f[i]; while(j && p[i]!=p[j]) j=f[j]; f[i+1]=(p[i]==p[j]?j+1:0); } } int main() { scanf("%s",p); getf(); int L=strlen(p); int i=L,k=0; while(f[i]>0) { if (f[i]) { a[k++]=f[i]; } i=f[i]; } printf("%d ",k+1); memset(dp,0,sizeof(dp)); for (int i=L;i>=0;i--) { dp[i]++; dp[f[i]]+=dp[i]; } for (int i=k-1;i>=0;i--) { printf("%d %d ",a[i],dp[a[i]]); } printf("%d 1",L); return 0; }
作者 chensunrise