InputThe input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) �C the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.
OutputFor each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.
Sample Input
3 aaa 12 aabaabaabaab 0
Sample Output
Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4
结论:j%(j-Nex[t])==0 说明该前缀是一个周期为j/(j-Next[j])的周期子序列
证明: j - Next[j] 是子串在失配时候的右移长度,说明在j位置失配的时候子串转移到next[j]处继续匹配,说明j之前的部分和next[j]之前的部分是相同的,也就是说j-Next[j]
是一个周期
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<string> #include<cstring> using namespace std; #define MAXN 1000001 typedef long long LL; /* */ char s[MAXN]; int Next[MAXN]; void kmp_pre(int m) { int j,k; j = 0; k = -1; Next[0] = -1; while(j<m) { if(k==-1||s[j]==s[k]) Next[++j] = ++k; else k = Next[k]; } } int main() { int m; int cas=1; while(scanf("%d",&m),m) { scanf("%s",s); kmp_pre(m); printf("Test case #%d\n",cas++); for(int i=1;i<=m;i++) if((i)%(i-Next[i])==0&&i/(i-Next[i])>1) printf("%d %d\n",i,(i)/(i-Next[i])); cout<<endl; } }