2015 UESTC Training for Search Algorithm & String - J - 全都是秋实大哥 【KMP】
给出一个字符串,求每个前缀的最小循环节长度,并输出整个字符串的最小循环节。字符串长度为3*10^6
找循环节这种问题还是要用KMP
对于长度为i的字符串 i%(i-f[i])==0 此时,它的最小循环节长度就是i-f[i],f[i]是字符串的第i位的失配函数(注意是从1开始算)
#include<bits/stdc++.h> #define eps 1e-9 #define FOR(i,j,k) for(int i=j;i<=k;i++) #define MAXN 1005 #define MAXM 40005 #define INF 0x3fffffff #define PB push_back #define MP make_pair #define X first #define Y second #define lc (k<<1) #define rc ((k<<1)1) using namespace std; typedef long long LL; int i,j,k,n,m,x,y,T,ans,big,cas,num,len; bool flag; char s[3000005]; int f[3000005]; void getFail(char *s,int *f) { int m=strlen(s),j; f[0]=0;f[1]=0; for (int i=1;i<m;i++) { j=f[i]; while (j&&s[i]!=s[j]) j=f[j]; f[i+1]=(s[i]==s[j]?j+1:0); } } int main() { scanf("%s",s); getFail(s,f); len=strlen(s); for (i=1;i<=len;i++) { if (i%(i-f[i])==0) { printf("%d ",i-f[i]); }else printf("%d ",i); } printf("\t\n"); printf("%s\n",s+f[len]); return 0; }