For each prefix 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 prefix 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 prefix 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.
3
aaa
12
aabaabaabaab
0
Test case #1
2 2
3 3
Test case #2
2 2
6 2
9 3
12 4
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int Next[1010000];
char a[1010000];
void getNext(){
int i = -1,j = 0;//两个下标错开
Next[0] = -1;//第一个初始化为-1
int lena = strlen(a);//求出字符串长度
while(j < lena){
if(i==-1||a[i]==a[j]){
i++,j++;
//if(a[i]==a[j])Next[j] = Next[i];//优化
Next[j] = i;//注意注意!!因为这里是单纯的找前缀中最长的前后缀相同长度,所以不能进行优化,优化长度就改变了
}
else i = Next[i];
}
}
int main(){
int n;
int i,j;
int num = 0;
while(~scanf("%d",&n)&&n){
scanf("%s",a);
getNext();
printf("Test case #%d\n",++num);
for(i = 1; i <= n; i++){
int temp = i-Next[i];//这句话求循环节的长度,仔细想想你会发现,如果不循环,那么i-Next[i]的值肯定大于前缀总长度的一般,而如果循环肯定小于等于一半
if(i%temp==0&&i/temp>1){//能整除说明是周期字符串,并且题目要求周期大于1
printf("%d %d\n",i,i/temp);
}
}
printf("\n");
}
return 0;
}