Period UVALive

来源:互联网 发布:服务端数据库 编辑:程序博客网 时间:2024/06/05 14:48

对于一段字符串来说,如果存在循环节,那么它的最小循环节一定是 ( 字符串的长度i - Next[i] ) (相当于最后一个循环节),那么直接判断(i % ( i - Next[i] ))就可以判断是不是存在循环节,还要注意Next[] > 0


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>using namespace std;const int maxn = 1000005;char str[maxn];int Next[maxn];int n ;void KMP(){    Next[0] = 0, Next[1] = 0;    for(int i = 1; i < n; i++)    {        int j = Next[i];        while(j && str[i] != str[j]) j = Next[j];        Next[i+1] = (str[i] == str[j] ? j+1 : 0);    }}int main(){    int cas = 1;    while(scanf("%d", &n) == 1 && n)    {        scanf("%s", str);        KMP();//        for(int i =  1 ;i <= n ; i++) cout << i << " " << Next[i] << endl;        printf("Test case #%d\n", cas++);        for(int i = 2; i <= n; i++)            if(Next[i] > 0 && i % ( i - Next[i] ) == 0)                printf("%d %d\n", i, i / (i - Next[i]));        printf("\n");    }    return 0;}