字串學習

Aqr_Rn發表於2024-11-04

manacher

馬拉車演算法( ,OI-Wiki

演算法介紹: 線性複雜度內找出以每個字元為迴文中心的最長迴文半徑

存下模板程式碼:

int l = 0, r = -1;
for(int i=1; i<=n; i++){
    int k = i > r ? 1 : min(d[l+r-i], r-i+1);
    while(i - k > 0 and k + i <= n and s[i-k] == s[i+k]) k++;
    d[i] = k--;
    if(r < i + k) l = i - k , r = i + k;
}

當時自己推的板子是個什麼構思

板子題: 【模板】manacher

code d ```cpp #include #define Aqrfre(x, y) freopen(#x ".in", "r", stdin),freopen(#y ".out", "w", stdout) #define mp make_pair #define Type ll #define qr(x) x=read() typedef __int128 INT; typedef long long ll; using namespace std;

inline ll read(){
char c=getchar(); ll x=0, f=1;
while(!isdigit(c)) (c=='-'?f=-1:f=1), c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48), c=getchar();
return x*f;
}

const int N = 2.2e7 + 10;

int n, d[N];
char in[N], s[N];

signed main(){ // a
// Aqrfre(a, a);

cin>>(in+1); n = strlen(in+1);

int cnt = 0;
for(int i=1; i<=n; i++)
    s[++cnt] = '@', s[++cnt] = in[i];
s[++cnt] = '@'; n = cnt;

int l = 0, r = -1, ans = 0;
for(int i=1; i<=n; i++){
    int k = i > r ? 1 : min(d[l+r-i], r-i+1);
    while(i - k > 0 and k + i <= n and s[i-k] == s[i+k]) k++;
    d[i] = k--;
    if(r < i + k) l = i - k , r = i + k;
}

for(int i=1; i<=n; i++){
    if(s[i] == '@') ans = max(ans, d[i] / 2 * 2); 
    else ans = max(ans, d[i] - !(d[i] & 1));
}
cout<<ans<<"\n";



return 0;

}

</details>

相關文章