poj 1961 Period
1 Description 2 3 For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as AK,that is A concatenated K times, for some string A. Of course, we also want to know the period K. 4 Input 5 6 The input consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S.The second line contains the string S. The input file ends with a line, having the 7 number zero on it. 8 Output 9 10 For each test case, output "Test case #" and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case. 11 Sample Input 12 13 3 14 aaa 15 12 16 aabaabaabaab 17 0 18 Sample Output 19 20 Test case #1 21 2 2 22 3 3 23 24 Test case #2 25 2 2 26 6 2 27 9 3 28 12 4
题意:(注意输出)
给定字符串S,求1-i的字符串的循环节(循环节长度要大于1)
解:
假设要求整个字符串的循环节 poj 2406
len为整个字符串的长度
想一想next[i]的含义
每次匹配失败后,都要回到next[i]开始重新匹配
也就是说 next[i]+1 -> len 这段字符 (令k为这段字符的长度)和
1 -> 1+k 这段字符 是相同的
OK,如果(len%(len-next[len])==0) ==> 存在 len/(len-next[len]) 段 解
否则只有1段
那么求1-i的字符串的循环节同理
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<string> 7 #include<queue> 8 #include<map> 9 using namespace std; 10 const int N=1e7; 11 char s[N]; 12 int len,ne[N],j,k; 13 int main() 14 { 15 while(scanf("%d",&len)!=EOF) 16 { 17 if(!len) break; 18 scanf("%s",s+1);k++; 19 printf("Test case #%d\n",k); 20 for(int i=0;i<=len;++i) ne[i]=0; 21 for(int i=2;i<=len;++i) 22 { 23 j=ne[i-1]; 24 while(j && s[i]!=s[j+1]) j=ne[j]; 25 if(s[i]==s[j+1]) ne[i]=j+1; 26 } 27 for(int i=1;i<=len;++i) 28 if(i%(i-ne[i])==0 && i/(i-ne[i])>1) 29 printf("%d %d\n",i,i/(i-ne[i])); 30 printf("\n"); 31 } 32 return 0; 33 }