题意:给定一个长度为n的字符串s,求它的每个前缀的最短循环节。即对于每个i(i>1),求一个最大的整数k>1,使得S的前i个字符组成的前缀是某个字符串重复K次得到。输出所
有存在K的i和对应的K。
分析:根据KMP中next数组的定义,当(i+1)%(i-next[i]) == 0时,其最短循环节即为(i-next[i]).
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n,num,Next[1001001];
string s;
int main()
{
cin.sync_with_stdio(false);
while(cin>>n && n)
{
cout<<"Test case #"<<++num<<endl;
cin>>s;
int m = s.length();
memset(Next,0,sizeof(Next));
int now = Next[0] = -1;
for(int i = 1;i < m;i++)
{
while(now >= 0 && s[now+1] != s[i]) now = Next[now];
if(s[now+1] == s[i]) now++;
Next[i] = now;
if(now >= 0 && (i + 1)%(i - now) == 0) cout<<i+1<<" "<<(i + 1)/(i - now)<<endl;
}
cout<<endl;
}
}