Period II(FZU-1901)

题面

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 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.

输出

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.

样例输入

14
2ooo
3acmacmacmacmacma
4fzufzufzuf
5stostootssto

样例输出

1Case #1: 3
21 2 3
3Case #2: 6
43 6 9 12 15 16
5Case #3: 4
63 6 9 10
7Case #4: 2
89 12

提示

思路

类似【题解】POJ-2752 Seek the Name, Seek the Fame。对于字符串的所有前缀,若存在循环节,输出符合条件的前缀个数与这个前缀字符串的长度。注意输出格式,行尾不得有多余空格。

代码

 1char t[mxn];
 2int nxt[mxn], ans[mxn];
 3
 4void getnxt(char* t, int m)
 5{
 6    int i = 0, j = -1; nxt[0] = -1;
 7    while (i < m)
 8    {
 9        if (j == -1 || t[i] == t[j]) {
10            i++, j++;
11            // if (t[i] == t[j])
12            //     nxt[i] = nxt[j]; // next数组优化
13            // else
14                nxt[i] = j;
15        } else
16            j = nxt[j];
17    }
18}
19
20int main()
21{
22    int T, cs=1; scanf("%d", &T);
23    while(T--)
24    {
25        scanf("%s", t);
26        int tl = strlen(t);
27        getnxt(t, tl);
28
29        int num = 0;
30        for(int i=tl; i>0; i=nxt[i]){
31            ans[num++] = tl-nxt[i];
32        }
33        printf("Case #%d: %d\n", cs++, num);
34        for(int i=0; i<num; i++){
35            if(i) printf(" ");
36            printf("%d", ans[i]);
37        }
38        printf("\n");
39    }
40    return 0;
41}