E - Period poj1611(kmp 计算前缀循环节)

E - Period

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

Submit Status

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
one) such that the prefix of S with length i can be written as A K , that is A concatenated K times, for some string A. Of course, we also want to know the period K.

Input

The input file 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
order. Print a blank line after each test case.

Sample Input

3

aaa

12

aabaabaabaab

0

t=i-next[i];表示已i结尾的前缀的循环节,关于kmp的next数组的性质,我前面的文章有介绍

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
//#include<bits/stdc++.h>
using namespace std;
template<class T>inline T read(T&x)
{
    char c;
    while((c=getchar())<=32)if(c==EOF)return 0;
    bool ok=false;
    if(c=='-')ok=true,c=getchar();
    for(x=0; c>32; c=getchar())
        x=x*10+c-'0';
    if(ok)x=-x;
    return 1;
}
template<class T> inline T read_(T&x,T&y)
{
    return read(x)&&read(y);
}
template<class T> inline T read__(T&x,T&y,T&z)
{
    return read(x)&&read(y)&&read(z);
}
template<class T> inline void write(T x)
{
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
template<class T>inline void writeln(T x)
{
    write(x);
    putchar('\n');
}
//-------ZCC IO template------
const int maxn=1000001;
const double inf=999999999;
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define For(i,t,n) for(int i=(t);i<(n);i++)
typedef long long  LL;
typedef double DB;
typedef pair<int,int> P;
#define bug printf("---\n");
#define mod  1000000007
int nex[maxn];
char a[maxn];

void getnext(char*s)
{
    int i=0,j=-1;
    nex[0]=-1;
    int len=strlen(s);
    while(i<len)
    {
        if(j==-1||s[i]==s[j])
            nex[++i]=++j;
        else
            j=nex[j];
    }
}
int main()
{
    //#ifndef ONLINE_JUDGE
    //freopen("in.txt","r",stdin);
    //freopen("zccccc.txt","w",stdout);
    //#endif // ONLINE_JUDGE
    int n,m,i,j,t,k;
    int T;
    int cas=1;
    while(read(n)&&n)
    {
        printf("Test case #%d\n",cas++);
        scanf("%s",a);
        int len=strlen(a);
        getnext(a);
        for(i=0;i<=len;i++)
        {
            t=i-nex[i];
            if(i%t==0&&i/t>1)
            {
                printf("%d %d\n",i,i/t);
            }
        }
        printf("\n");
    }

    return 0;
}
时间: 2025-01-02 13:50:55

E - Period poj1611(kmp 计算前缀循环节)的相关文章

(KMP扩展 利用循环节来计算) Cyclic Nacklace -- hdu -- 3746

http://acm.hdu.edu.cn/showproblem.php?pid=3746 Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4498    Accepted Submission(s): 2051 Problem Description CC always becomes very dep

KMP + 求最小循环节 --- POJ 2406 Power Strings

Power Strings Problem's Link: http://poj.org/problem?id=2406 Mean: 给你一个字符串,让你求这个字符串最多能够被表示成最小循环节重复多少次得到. analyse: KMP之next数组的运用.裸的求最小循环节. Time complexity: O(N) Source code:  /** this code is made by crazyacking* Verdict: Accepted* Submission Date: 20

KMP + 求最小循环节 --- HDU 1358 Period

Period Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=1358 Mean: 给你一个字符串,让你从第二个字符开始判断当前长度的字符串是否是重复串,如果是,输出当前位置,并输出重复串的周期. analyse: 还是next数组的运用,详见上一篇博客. Time complexity: O(N) Source code:  /** this code is made by crazyacking* Verdict: Acce

模板题 + KMP + 求最小循环节 --- HDU 3746 Cyclic Nacklace

Cyclic Nacklace Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3746 Mean: 给你一个字符串,让你在后面加尽量少的字符,使得这个字符串成为一个重复串. 例: abca---添加bc,成为abcabc abcd---添加abcd,成为abcdabcd aa---无需添加 analyse: 经典的求最小循环节. 首先给出结论:一个字符串的最小循环节为:len-next[len]. 证明: 举个例子:abcab

poj 1961 KMP运用之循环节的问题

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; char str[1000010]; int next[1000010]; int get_next(int len) { next[0]=-1; int i=0,k=-1; while(i<len) { if(k==-1||str[i]==str[k]) { i++; k++; next[i]=k; } els

poj 1961 Period【求前缀的长度,以及其中最小循环节的循环次数】

Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 14653   Accepted: 6965 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

(KMP 1.5)hdu 1358 Period(使用next数组来求最小循环节——求到第i个字符的循环节数)

题目: Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3813    Accepted Submission(s): 1862 Problem Description For each prefix of a given string S with N characters (each character has an A

Uvalive - 3026 Period (kmp求字符串的最小循环节+最大重复次数)

参考:http://www.cnblogs.com/jackge/archive/2013/01/05/2846006.html 总结一下,如果对于next数组中的 i, 符合 i % ( i - next[i] ) == 0 && next[i] != 0 , 则说明字符串循环,而且 循环节长度为:   i - next[i] 循环次数为:       i / ( i - next[i] ) 1 #include <iostream> 2 #include <cstdi

Period(KMP,循环节问题)

题意: 求给你个串,前i位子串由某个字符串重复k次得到,求所有的i和k 分析: i-next[i]恰好是一个循环节 #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <str