[KMP][BZOJ1355][Baltic2009]Radio Transmission

题面

Description

给你一个字符串,它是由某个字符串不断自我链接造成的。 可是这个字符串是不肯定的,如今只想知道它的最短长度是多少。ios

Input

第一行给出字符串的长度,\(1 < L \le 1,000,000\). 第二行给出一个字符串,全由小写字母组成。数组

Output

输出最短的长度。spa

SampleInput

8
cabcabca

SampleOutput

3

Hint

对于样例,咱们能够利用"abc"不断自我链接获得"abcabcabc",读入的cabcabca,是它的子串。code


首先让咱们来研究一下结果的含义。ip

不妨设结果为串\(T\)。 则原串为:字符串

咱们怎样利用起KMP中的nxt数组呢?input

因为\(T\)串是最小循环子串,因此能够标出KMP中\(nxt[n]\)(n为\(|A|\))为:string

结果为n-nxt[n]!可是为何呢?io

若是T不是最小循环子串的话,nxt[n]一定还能够再加长模板

不然,\(nxt[n]\)若再往左边扩展,不妨设增加的为\(T2\),剩下的\(T1\),分两种状况讨论。

1.\(|T1|>=|T2|\)

将两个串对齐可得:


若两串匹配,则显然可得\(T2\)\(T1\)的前缀,即\(T1=T2+R\),且\(R\)也是\(T1\)的前缀,余下的为\(T2\),即\(T1=R+T2\),则显然\(T1\)是比\(T\)更小的循环子串,与前设矛盾
故两串一定不匹配。
***

2.\(|T1|<|T2|\)

将两个串对齐可得:

同理。

若两串匹配,则显然可得\(T1\)\(T2\)的前缀,即\(T2=T1+R\),且\(R\)也是\(T2\)的前缀,余下的为\(T1\),即\(T2=R+T1\),则显然\(T2\)是比\(T\)更小的循环子串,与前设矛盾
故两串一定不匹配。

这样一来,咱们就证实了答案为\(n-nxt[n]\)!

而后就能够直接套KMP模板了。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int nxt[1000001],n;
char a[1000001];
int main(){
    scanf("%d%s",&n,a);
    int k=0;
    for(int i=2;i<=n;i++){
        while(k&&a[k]!=a[i-1])k=nxt[k];
        if(a[k]==a[i-1])k++;
        nxt[i]=k;
    }
    printf("%d\n",n-nxt[n]);
}
相关文章
相关标签/搜索