和hdu3746差不多,可以先去看一下这篇博客:https://blog.csdn.net/qq_43227036/article/details/99068551
上面的博客求得是对于整个字符串得循环节,而这道题要所有循环节大于一得前缀,只需要把上面求循环节得len变为i就是当前前缀得循环节求法了。i%(i-Next[i])是循环节得长度,需要其满足等于0,然后是i/(i-Next[i])需要满足其不等于1,也就是循环得次数不能是一次。
AC代码:
#include<stdio.h>
#include<string.h>
int p[1000010];
char str[1000010];
void getp(int len) //getp函数,求字符串的next[]数组值
{
int i=0,j=-1;
p[i]=j;
while(i<len)
{
if(j==-1||str[i]==str[j])
{
i++;j++;p[i]=j;
}
else
j=p[j];
}
}
int main()
{
int n,i,j,ans=1;
while(scanf("%d",&n)&&n)
{
memset(str,0,sizeof(str));
scanf("%s",str);
getp(n);
j=0;
printf("Test case #%d\n", ans++);
for(i=2;i<=n;i++)
{
if(i%(i-p[i])==0&&i/(i-p[i])!=1)
{
printf("%d %d\n", i, i/(i-p[i]));
}
}
printf("\n");
}
return 0;
}