[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]);
}
相關文章
相關標籤/搜索