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 }
View Code

 

posted @ 2015-12-03 15:39  cdongyang  阅读(145)  评论(0编辑  收藏  举报