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

posted @ 2018-03-13 18:55  月亮茶  阅读(137)  评论(0编辑  收藏  举报