题意:给你一个字符串,问第i位前是否有循环节,若存在,则循环节是多少?
思路:考察失配函数f[i]的意义。只要i%(i-f[i])==0,则循环节长度为i/(i-f[i])。字符在[0,f[i]],[i-f[i],i]范围内的相等,所以如果存在循环节则每i-f[i]可以分为一段。理解起来比较抽象,模拟一遍。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <time.h>
#define clc(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = ;
const int inf=0x3f3f3f3f;
typedef long long LL;
char P[maxn];
int f[maxn]; int main()
{
int n,cas=;
while(~scanf("%d",&n),n)
{
scanf("%s",P);
f[]=,f[]=;
for(int i=;i<n;i++)
{
int j=f[i];
while(j&&P[i]!=P[j])
j=f[j];
f[i+]=(P[i]==P[j]?j+:);
}
printf("Test case #%d\n",++cas);
for(int i=;i<=n;i++)
{
if(f[i]&&i%(i-f[i])==)
printf("%d %d\n",i,i/(i-f[i]));
}
printf("\n");
}
return ;
}