P4555 [国家集训队]最长双回文串 - PAM

len是以尾部为point[ i ]的最长回文长度,如果反着建就有以len为头的最长回文长度。相加可得,可以定义一个id来确定尾坐标与point之间的关系。#include <bits/stdc++.h>using namespace std;const int MAXN = 300000 , MAXK = 26;char str[ MAXN + 5 ];struct Palindrome_Automaton{ int Size = 0 //总节点 , Last ,
摘要由CSDN通过智能技术生成

len是以尾部为point[ i ]的最长回文长度,如果反着建就有以len为头的最长回文长度。相加可得,可以定义一个id来确定尾坐标与point之间的关系。

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 300000 , MAXK = 26;
char str[ MAXN + 5 ];

struct Palindrome_Automaton{
    int Size = 0 //总节点
    , Last , Root0 , Root1 , Trans[ MAXN + 5 ][ MAXK + 5 ] , Fail[ MAXN + 5 ];int id[MAXN];
    long long  Len[ MAXN + 5 ];
    Palindrome_Automaton( ) {
        Root0 = Size ++ , Root1 = Size; Last = Root1;
        Len[ Root0 ] = 0  , Fail[ Root0 ] = Root1;
        Len[ Root1 ] = -1 , Fail[ Root1 ] = Root1;
    }
    void Extend( int ch , int dex ) {
        int u = Last;
        while (str[ dex - Len[ u ] - 1 ] != str[ dex ] ) u = Fail[ u ]; //找到合格的后缀
        if( !Trans[ u ][ ch ] ) {         //无现成的边
            int Newnode = ++ Size , v = Fail[ u ];    //防止取掉整串
            Len[ Newnode ] = Len[ u ] + 2;
            while (str[ dex - Len[ v ] - 1 ] != str[ dex ] ) v = Fail[ v ];    //给他找一个fail指针
            Fail[ Newnode ] = Trans[ v ][ ch ] , Trans[ u ][ ch ] = Newnode;
        }
        Last = Trans[ u ][ ch ];
        id[dex] = Last;
    }

    void Build() {
        int len = strlen( str +1);
        for( int i = 1 ; i <= len ; i ++ ) {
            Extend( str[ i ] - 'a' + 1 , i );
        }
    }
}PAM,PAM1;
signed main( ) {
    cin >>( str+1 );
    int len  = strlen(str+1);
    PAM.Build();
    reverse(str+1,str+len+1);
    PAM1.Build();
    long long  ans = 0;
    for (int i = 1; i < len; ++i) {
        ans = max(ans,PAM.Len[PAM.id[i]] + PAM1.Len[ PAM1.id[len-i]]);
    }
    cout << ans;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值