Language: Default Period
Description 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 Input 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 number zero on it. Output 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 Sample Input 3 aaa 12 aabaabaabaab 0 Sample Output Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4 Source |
题意:求长度为i(2<=i<=N)的前缀,若前缀是一个周期串,则输出长度i和它的最大周期;要找出所有满足条件的。
思路:next[i]数组里面存的是i位置前 字符串的相同前缀和后缀的最大长度,若它是一个周期串,那它必满足i%(i-next[i])==0.
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define maxn 1005 #define MAXN 1000010 #define mod 1000000009 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-6 typedef long long ll; using namespace std; int next[MAXN]; char str[MAXN]; int N; void get_next() { int i=0,j=-1; next[0]=-1; while (i<N) { if (j==-1||str[i]==str[j]) { i++; j++; next[i]=j; } else j=next[j]; } } void KMP() { for (int i=1;i<=N;i++) //枚举所有长度,看它满不满足要求 { if (!(i%(i-next[i]))&&(i/(i-next[i]))>1)//满足就输出 printf("%d %d\n",i,i/(i-next[i])); } } int main() { int cas=1; while (scanf("%d",&N)&&N) { scanf("%s",str); get_next(); printf("Test case #%d\n",cas++); KMP(); printf("\n"); } return 0; } /* 3 aaa 12 aabaabaabaab 0 */