P4555最长双回文串(Manacher)

传送门
题意:给定一个字符串,求出最长的双回文串长度。
思路:先跑一边Manacher,再求出每个字符所在回文串中,处在右侧且最长的子串中心,和处在左侧且最长的子串中心,最后拼接起来找最长的即可

#include<iostream>
#include<cstring>
using namespace std;
const int MAXN = 11000000+5;

int n;
char a[MAXN], s[MAXN*2];
int len[MAXN*2];
int _left[MAXN*2], _right[MAXN*2]; //分别表示i所在回文串中,i处于右侧且最长的回文串中心,i处于左侧且最长的回文串中心
void manacher(){
    //预处理
    s[0] = '$'; s[1] = '#';
    for(int i = 0; i < n; ++i){
        s[2*i+2] = a[i];
        s[2*i+3] = '#';
    }
    n = 2*n+2;
    s[n] = 0;

    //manacher
    int max_right = 0, mid = 0;
    for(int i = 1; i < n; ++i){
        if(i < max_right) len[i] = min(len[2*mid-i], len[mid]+mid-i);
        else len[i] = 1;
        while(s[i+len[i]] == s[i-len[i]])
            len[i]++;
        if(len[i] > len[mid]){
            max_right = i+len[i];
            mid = i;
        }
    }
}

int main(){
    cin >> a;
    n = strlen(a);
    manacher();

    int cur = 1;
    for(int i = 1; i < n; ++i){
        while(cur <= i+len[i]-1)
            _left[cur++] = i;
    }
    cur = n-1;
    for(int i = n-1; i >= 1; --i){
        while(cur >= i-len[i]+1)
            _right[cur--] = i;
    }
    int ans = 0;
    for(int i = 2; i < n-2; i = i+2){
        ans = max(ans, i-_left[i]+1+_right[(i+2)]-(i+2)+1);
    }
    cout << ans << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值