小a的回文串 -- (最长回文字串模板)

链接:https://ac.nowcoder.com/acm/contest/549/B

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 100;
 
int cnt, len, ans = 0;
char s[maxn], ss[maxn * 2];
int p[maxn * 2];
 
void init(){//将每两个字符中插入一个字符
    ans = 0;
    cnt = 1;
    ss[0] = '!';
    ss[cnt] = '#';
    for(int i = 0; i < len; i++)
    ss[++cnt] = s[i], ss[++cnt] = '#';
    ss[++cnt] = '\0';
    //cout<<ss<<endl;
}
 
void manacher(){
    init();  //dcbaabc -> ss:!#d#c#b#a#a#b#c#d#c#b#a#a#b#c#
    int pos = 0, mx = 0;
    for(int i = 1; i <= cnt; i++){
        if(i < mx) p[i] = min(p[pos * 2 - i], mx - i);
        else p[i] = 1;
        while(ss[i + p[i]] == ss[i - p[i]]) p[i]++;
        if(mx < i + p[i]) mx = i + p[i], pos = i;
        ans = max(ans, p[i] - 1);
        	cout<<i<<" "<<p[i]<<" "<<mx<<" "<<pos<<" "<<ans<<endl;
    }
}
 
int main(){
    scanf("%s", s);
    len = strlen(s);
    for(int i = len; i < 2 * len; i++) s[i] = s[i - len];
    s[2 * len] = '\0';
    //for(int i = len;i<2*len;++i)
    //cout<<s[i]<<endl;
    len *= 2;
    manacher();
    if(ans > len / 2) ans = len / 2;
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dukig/article/details/89278619