This documentation is automatically generated by online-judge-tools/verification-helper
#include "String/mp.hpp"
mp法を行う。 参考:https://snuke.hatenablog.com/entry/2014/12/01/235807
長さが $n$ の文字列 $S$ について、次の命題が成立する。
Sが周期長kを持つ⇔Sと、Sをk文字右にずらした文字列の共通部分が一致する⇔S[0, n-k] = S[k, n]
また、次の命題も成立する
S[0, n-k] = S[k, n] ⇔ Sの最長共通文字列であって、n未満の長さの物の長さ >= n-k
合わせて、
Sが周期kを持つ ⇔ mp[n-1] >= n - k
これを、mp法の形式に合わせると、
S[0, i]が周期kを持つ ⇔ mp[i] >= i+1 - k
となって
S[0, i]の最小周期長 = i+1 - mp[i]
vec<int> MP(string S) {
int n = S.size();
vec<int> res(n+1, -1);
int j = -1;
rep(i, 0, n) {
while(j >= 0 && S[i] != S[j]) j = res[j];
j++;
res[i+1] = j;
}
res.erase(res.begin());
return res;
}
int shortest_run(vec<int> &mp, int i) {
return i + 1 - mp[i];
}
/*
@brief mp法
@docs doc/mp.md
*/
#line 1 "String/mp.hpp"
vec<int> MP(string S) {
int n = S.size();
vec<int> res(n+1, -1);
int j = -1;
rep(i, 0, n) {
while(j >= 0 && S[i] != S[j]) j = res[j];
j++;
res[i+1] = j;
}
res.erase(res.begin());
return res;
}
int shortest_run(vec<int> &mp, int i) {
return i + 1 - mp[i];
}
/*
@brief mp法
@docs doc/mp.md
*/