BZOJ 1355: [Baltic2009]Radio Transmission [KMP 循环节]

1355: [Baltic2009]Radio Transmission

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 792  Solved: 535
[Submit][Status][Discuss]

Description

给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.

Input

第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.

Output

输出最短的长度

Sample Input

8
cabcabca

Sample Output

3

HINT

对于样例,我们可以利用"abc"不断自我连接得到"abcabcabc",读入的cabcabca,是它的子串


n-fail[n]

fail[n]>n/2时,循环节的性质

fail[n]<n/2时,要满足不断连接的话就只能n-fail[n]那么长了

1.循环节移位一下仍是循环节

2.循环节重叠后会自我重复

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,fail[N];
char s[N];
void getFail(){
    fail[1]=0;
    for(int i=2;i<=n;i++){
        int j=fail[i-1];
        while(j&&s[i]!=s[j+1]) j=fail[j];
        fail[i]=s[i]==s[j+1]?j+1:0;
    }
}
int main(){
    freopen("in.txt","r",stdin);
    scanf("%d%s",&n,s+1);
    getFail();
    printf("%d",n-fail[n]);
}

 

 

 

 

posted @ 2017-02-04 17:04  Candy?  阅读(231)  评论(0编辑  收藏  举报