【BZOJ】2565最长双回文串-回文自动机

题解

这题可以马拉车水过。拿回文自动机来做一做也是一样的。
li l i 表示以第i个字符为末位置的字符串前缀的最大回文后缀。 ri r i 表示以第i个字符为首位置的字符串后缀的最大回文前缀。
那么就正着反着各做一遍回文自动机。
注意这里struct两个就好了,千万不要省空间第二遍memset用同一个数组,貌似我 O(n26) O ( n ∗ 26 ) 就TLE了。还debug了许久。
另外注意
求答案就 O(n) O ( n ) 遍历一遍取max。
写回文自动机一定要注意一点!
在增量时,一定要在建完 fail[now] f a i l [ n o w ] 以后再把 ch[last][alp] c h [ l a s t ] [ a l p ] 设为 now n o w
不然会死循环QWQ


代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int ans,n,l[N],r[N];
char s[N];

struct P{
    int cnt,ch[N][26],p,f[N],len[N];
    inline int new_node(int m)
{
    len[cnt]=m;return cnt++;
}

inline int get_fail(int x,int m)
{
    for(;s[m-len[x]]!=s[m+1];)
    x=f[x];
    return x;
}

inline void insert(int alp,int m,int op)
{
    p=get_fail(p,m);
    if(!ch[p][alp]){
        int now=new_node(len[p]+2);
        f[now]=ch[get_fail(f[p],m)][alp];
        ch[p][alp]=now;
    }
    p=ch[p][alp];
    if(!op) l[m+1]=len[p];
    else r[n-m]=len[p];
} 
}A,B;



int main(){
    int i;
    scanf("%s",s+1);n=strlen(s+1);
    A.new_node(0);A.new_node(-1);A.f[0]=1;
    for(i=1;i<=n;++i) A.insert(s[i]-'a',i-1,0);
    B.new_node(0);B.new_node(-1);B.f[0]=1;
    reverse(s+1,s+n+1);
    for(i=1;i<=n;++i) B.insert(s[i],i-1,1);
    for(i=1;i<n;++i) 
    ans=max(ans,l[i]+r[i+1]);
    printf("%d\n",ans); 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值