UVALive - 3026 Period kmp next数组的应用
input
n 2<=n<=1000000
长度为n的字符串,只含小写字母
output
Test case #cas
长度为i时的最小循环串 循环次数(>1)
若没有则不输出
做法:若next数组是连续的整数且next[i]+1是错位部分长度的倍数,则必有循环出现,且循环次数为(i+1)/错位部分长度
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #include <cctype> 13 #define MAX 100000 14 #define LL long long 15 int cas=1,T,n,f[MAX*10+10]; 16 char s[MAX*10+10]; 17 void getFail(char*s,int*f) 18 { 19 f[0]=0;f[1]=0; 20 for(int i=1;i<n;i++) 21 { 22 int j=f[i]; 23 if((j+1)%(i-j)==0&&s[i]==s[j]) printf("%d %d\n",i+1,(i+1)/(i-j)); 24 while(j&&s[i]!=s[j]) j=f[j]; 25 f[i+1]=s[i]==s[j]?j+1:0; 26 } 27 } 28 int main() 29 { 30 //freopen("/home/user/桌面/in","r",stdin); 31 //scanf("%d\n",&T); 32 while(scanf("%d",&n)==1&&n) 33 { 34 scanf("%s",s); 35 printf("Test case #%d\n",cas++); 36 getFail(s,f); 37 printf("\n"); 38 } 39 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 40 return 0; 41 }