G - Next[]樹 CodeForces - 432D
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 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 substring ci times. Print pairs li ci in the order of increasing li.
Example
Input
ABACABA
Output
3
1 4
3 2
7 1
Input
AAA
Output
3
1 3
2 2
3 1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1e5+10;
char s[maxn];
int Next[maxn], saveLen[maxn], occurrence[maxn], num[maxn];
void getNext(){
int len = strlen(s);
int j;
Next[0] = Next[1] = 0;
for(int i = 1; i < len; i++){
j = Next[i];
while(j && s[i] != s[j])
j = Next[j];
if(s[i] == s[j])
Next[i + 1] = j + 1;
else
Next[i + 1] = 0;
}
}
int main(){
#ifdef TEST
freopen("test.txt", "r", stdin);
#endif // TEST
while(scanf("%s", s) != EOF){
getNext();
int cnt = 0, len = strlen(s);
for(int i = 0; i <= len; i++)
occurrence[i] = 1;
for(int i = len; i >= 1; i--)
occurrence[Next[i]] += occurrence[i];
int temp = len;
while(temp){
num[cnt] = occurrence[temp];
saveLen[cnt] = temp;
cnt++;
temp = Next[temp];
}
cout << cnt << endl;
for(int i = cnt - 1; i >= 0; i--)
cout << saveLen[i] << " " << num[i] << endl;
}
return 0;
}