P3435 [POI2006]OKR-Periods of Words KMP演算法擴充套件
阿新 • • 發佈:2020-09-16
題意:
對於一個僅含小寫字母的字串$q,p$ 為 \(a\) 的字首且 \(a \ne p\),那麼我們稱 \(p\) 為 \(a\) 的 proper 字首。
規定字串 \(Q\)(可以是空串)表示 \(a\) 的週期,當且僅當 \(Q\) 是 \(a\) 的 proper 字首且 \(a\) 是 $Q+Q$的字首。
例如 ab
是 abab
的一個週期,因為 ab
是 abab
的 proper 字首,且 abab
是 ab+ab
的字首。
求給定字串所有字首的最大週期長度之和。
範圍&性質:$1\le k\le 10^6$
分析:
借用別人的圖,侵刪
這裡利用了next陣列的性質:$next[i]$表示$i$的最長的字首和字尾相同的長度
如圖可得對於字串$i$,令$j=i$,然後在$j>0$的情況下令$j=next[j]$最大週期就是$i-j$
程式碼:
#include<bits/stdc++.h> using namespace std; namespace zzc { const int maxn = 1e6+5; int n; long long ans; char ch[maxn]; int nxt[maxn]; void work() { scanf("%d",&n); scanf("%s",ch+1); for(int i=2,j=0;i<=n;i++) { while(j&&ch[i]!=ch[j+1]) j=nxt[j]; if(ch[i]==ch[j+1]) j++,nxt[i]=j; } for(int i=2,j=2;i<=n;i++,j=i) { while(nxt[j]) j=nxt[j]; if(nxt[i]) nxt[i]=j; ans+=i-j; } printf("%lld",ans); } } int main() { zzc::work(); return 0; }