Problem 1901 Period II
Accept: 676 Submit: 1825
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
For each prefix with length P of a given string S,if
S[i]=S[i+P] for i in [0..SIZE(S)-p-1],
then the prefix is a “period” of S. We want to all the periodic prefixs.
Input
Input contains multiple cases.
The first line contains an integer T representing the number of cases. Then following T cases.
Each test case contains a string S (1 <= SIZE(S) <= 1000000),represents the title.S consists of lowercase ,uppercase letter.
Output
For each test case, first output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the number of periodic prefixs.Then output the lengths of the periodic prefixs in ascending order.
Sample Input
4oooacmacmacmacmacmafzufzufzufstostootssto
Sample Output
Case #1: 31 2 3Case #2: 63 6 9 12 15 16Case #3: 43 6 9 10Case #4: 29 12
Source
FOJ有奖月赛-2010年05月
找最小循环节周期统计答案便可
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 1000024;
int ans[MAX_N];
int Next[MAX_N];
char mo[MAX_N];
int n2;
void getnext(){
int i = 0,j=-1;
while(i<n2){
if(j==-1||mo[i]==mo[j]) {++i,++j,Next[i]=j;}
else j = Next[j];
}
return ;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int cnt = 0;
scanf("%s",mo);
n2 = strlen(mo);
Next[0] = -1;
getnext();
int tmp = n2-Next[n2];
for(int i=1;;i++){
if(tmp*i>=n2) break;
ans[cnt++] = tmp*i;
}
ans[cnt++] = n2;
printf("Case #%d: %d\n",i,cnt);
for(int k=0;k<cnt;++k){
k==cnt-1?printf("%d\n",ans[k]):printf("%d ",ans[k]);
}
}
return 0;
}