Problem Description
For each prefix of a given string Swith N characters (each character has an ASCII code between 97 and 126,inclusive), we want to know whether the prefix is a periodic string. That is,for each i (2 <= i <= N) we want to know the largest K > 1 (if thereis one) such that the prefix of S with length i can be written as AK, that is A concatenated K times, for some string A. Of course, we also want toknow the period K.
Input
The input file consists of severaltest cases. Each test case consists of two lines. The first one contains N (2<= N <= 1 000 000) – the size of the string S. The second line containsthe string S. The input file ends with a line, having the number zero on it.
Output
For each test case, output “Testcase #” and the consecutive test case number on a single line; then, for eachprefix with length i that has a period K > 1, output the prefix size i andthe period K separated by a single space; the prefix sizes must be inincreasing 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
kmp得出next数组,发现字符串的周期k就是字符对应的下标减去next数组中的值,但不是每一个数都满足在整体字符串中是一个周期串,当字符对应的下表能被周整除时说明是一个周期串,而周期即为下标除以k
#include<stdio.h>
#include<string.h>
int lena,lenb;
char a[1000010];
int next[1000010];
void get_next()
{
int i=1,j=0;
next[0]=0;
while(i<lena)
{
if(j>0 && a[i]!=a[j])
{
j=next[j-1];
}
else if(j==0 && a[i]!=a[j])
{
next[i]=0;
i++;
}
else
{
next[i]=j+1;
i++;
j++;
}
}
// for(i=0;i<lena;i++)
// printf("%d ",next[i]);
int k=0;
for(i=1;i<lena;i++)
{
k=i+1-next[i];
if((i+1)%k==0 && next[i]!=0)
printf("%d %d\n",i+1,(i+1)/k);
}
}
int main()
{
int len,i,flag=0;
while(scanf("%d",&lena),lena!=0)
{
scanf("%s",a);
flag++;
//if(flag>1)
// printf("\nTest case #%d\n",flag);
//else
printf("Test case #%d\n",flag);
get_next();
printf("\n");
}
return 0;
}