POJ2406Power Strings (最小循环节)(KMP||后缀数组)

Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

Input

Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

For each s you should print the largest n such that s = a^n for some string a.

Sample Input

abcd
aaaa
ababab
.

Sample Output

1
4
3

题意:

对于字符串S=x+x+x+...,x=“   ”一段字符,我们定义x为S的循环节,现在要找S做多由多少个循环节组成。即找最小循环节。

比如S="abababab",则“ab”“abab”都是S的循环节,但x=“ab”是最小的,满足答案ans=8/2=4是最大的。

思路:

kmp:

此题关键在于求出最长循环节的长度,假设一个字符串长度为n,循环节长度为m,一定n是m的倍数,根据KMP算法Next数组的含义,假设一个字符串是由K个子串组成的,则字符串最后一个字符的Next数值一定是K-1个子串的长度,所以只需求出Next[n]后n-Next[n]就是可能的最长循环节,但是如果n-Next[n]不能整除n,则一定原字符串无循环,所以最后模判定一下就行了。

后缀数组:

见下一个题。

KMP解决最小循环节:

例如 

ababab  next[6] = 4; 即

123456

    ababab

ababab

1~4位  与3~6位是相同的 

那么1,2位

就等于3、4位

3、4位就等于5、6位

……

所以 如果 能整除  也就循环到最后了;

如果不能整除  ,

就最后余下的几位不在循环内。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<memory>
using namespace std;
const int maxn=1000010;
char c[maxn];
int Next[maxn],L;
void KMP()
{
    Next[1]=0;
    for(int i=2,k=0;i<=L;i++) {
        while(k&&c[i]!=c[k+1]) k=Next[k];
        if(c[i]==c[k+1]) k++;
        Next[i]=k;
    }
}
int main()
{
    while(~scanf("%s",c+1)){
        if(c[1]=='.') return 0;
        L=strlen(c+1);
        KMP();
        if(L%(L-Next[L])==0) printf("%d
",L/(L-Next[L]));
        else printf("1
");
    }
}
原文地址:https://www.cnblogs.com/hua-dong/p/8016873.html