For each pre x of a given string S with N characters (each character
has an ASCII code between 97 and 126, inclusive), we want to know
whether the pre x is a periodic string. That is, for each i (2 i N
) we want to know the largest K > 1 (if there is one) such that the
pre x of S with length i can be written as A K , that is A
concatenated K times, for some string A . Of course, we also want to
know the period K . Input The input le consists of several test
cases. Each test case consists of two lines. The rst one contains N
(2 N 1000000) the size of the string S . The second line contains
the string S . The input le ends with a line, having the number zero
on it. Output For each test case, output ` Test case # ’ and the
consecutive test case number on a single line; then, for each pre x
with length i that has a period K > 1, output the pre x size i and the
period K separated by a single space; the pre x sizes must be in
increasing order. Print a blank line after each test case.
利用kmp算法,对于位置i,最短的循环节是i-next[i]。判断i是否能整除它即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char s[1000010];
int ne[1000010];
int main()
{
int i,j,l,K=0;
while (scanf("%d",&l)&&l)
{
scanf("%s",s+1);
printf("Test case #%d\n",++K);
for (i=2,j=0;i<=l;i++)
{
while (j&&s[j+1]!=s[i]) j=ne[j];
if (s[j+1]==s[i]) j++;
ne[i]=j;
if (ne[i]&&i%(i-ne[i])==0) printf("%d %d\n",i,i/(i-ne[i]));
}
printf("\n");
}
}