题目链接
题目描述(Description)
给定一个字符串S(长度2 <= N <= 1 000 000),只包含小写字母,找出S的循环前缀的长度和循环的周期。
例如:
输入:
aaa
输出:
2 2
3 3
输入:
aabaabaabaab
输出:
2 2
6 2
9 3
12 4
分析(Analysis)
KMP算法的又一大应用。
先求出S串的
next
数组。如果出现循环前缀,那么循环节的长度是
length=i(下标)-next(i)
,循环前缀结束的出现在i%length==0
的时候。
代码(Code)
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000010;
char s[maxn];
int next[maxn];
int len;
void get_next()
{
next[0]=-1;
int j=0,k=-1;
while(j<len)
{
if(k==-1||s[j]==s[k])
{
next[++j]=++k;
}
else
k=next[k];
}
}
int main()
{
int kase=0;
while(scanf("%d",&len)&&len!=0)
{
scanf("%s",s);
memset(next,0,sizeof(next));
get_next();
printf("Test case #%d\n",++kase);
for(int i=2;i<=len;i++)
{
if(next[i]==0)
continue;
int length=i-next[i];
if((i%length)==0)
printf("%d %d\n",i,i/length);
}
printf("\n");
}
return 0;
}