
UVA10298:https://www.luogu.org/problemnew/show/UVA10298
思路
设P[x]数组为 前x个字符的最大前缀长度等于后缀字串
由P数组的定义我们可以知道 对于给定的长度为n字符串
则n-P[n]所在位置就是这个字符串的重复最长子串的最后一个字符的位置
如果这个字符串真的是由其中的一个子串循环而成 那么它的长度肯定是n-P[n]的倍数
因此我们用KMP预处理出给定字符串的所有P数组
再判断n是否整除n-P[n]即可 如果整除ans=n/(n-P[n])
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1000010
char a[maxn];
int p[maxn];
int len,j;
int main()
{
for(;;)//死循环
{
cin>>a+;//从下标1开始输入
if(a[]=='.') break;
len=strlen(a+);
for(int i=;i<=len;i++)//常规KMP
{
while(j&&a[j+]!=a[i]) j=p[j];
if(a[j+]==a[i]) j++;
p[i]=j;
}
if(len%(len-p[len])==)//如果可以整除
cout<<len/(len-p[len])<<endl;//输出ans
else
cout<<<<endl;//无解
j=;//记得清0
}
}