http://acm.fzu.edu.cn/problem.php?pid=1901

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#problem/Q

 

Period II
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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

4
ooo
acmacmacmacmacma
fzufzufzuf
stostootssto

Sample Output

Case #1: 3
1 2 3
Case #2:
6 3 6 9 12 15 16
Case #3: 4
3 6 9 10
Case #4: 2
9 12
 
给你一个字符串 s 求出所有满足s[i] == s[i+p] ( 0 < i+p < len )的 p ;
 
其实就是这个字符串的后缀与前缀的最大匹配 next[N],然后用最大匹配的串继续找匹配的前缀,比如下面的数据:
 
aaabaaa:--> P = 4  <---> next[7] = 3
aaabaaa:--> P = 5  <---> next[3] = 2
aaabaaa:--> P = 6  <---> next[2] = 1
aaabaaa:--> P = 7  <---> next[1] = 0
 
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;

const int maxn = 1000050;

char s[maxn];
int Next[maxn], ans[maxn];

void FindNext(char s[])
{
    int slen = strlen(s), i=0, j=-1;
    Next[0] = -1;

    while(i<slen)
    {
        if(j==-1 || s[i]==s[j])
            Next[++i] = ++j;
        else
            j = Next[j];
    }
}

int main()
{
    int t, iCase=1;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%s", s);

        int len = strlen(s);

        FindNext(s);

        int cnt = 0, k=len;

        while(Next[k]!=0)
        {
            ans[cnt++] = len-Next[k];  /// 第 cnt 个子串结束的下标, 表示自己觉得很神奇
            k = Next[k];
        }

        printf("Case #%d: %d\n", iCase++, cnt+1);
        for(int i=0; i<cnt; i++)
            printf("%d ", ans[i]);
        printf("%d\n", len);
    }
    return 0;
}

 

 
 
 
 
posted on 2015-09-30 16:28  栀蓝  阅读(297)  评论(0编辑  收藏  举报

levels of contents