BZOJ 3676 回文串

回文子串最大出现值
本文介绍了一道关于寻找字符串中回文子串最大出现值的问题,通过构建回文自动机并结合类似拓扑排序的方法来高效解决该问题。

Description

考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 
现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 
大出现值。 

Input

输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。 

Output


输出一个整数,为逝查回文子串的最大出现值。 

Sample Input

【样例输入l】
abacaba

【样例输入2]
www

Sample Output

【样例输出l】
7

【样例输出2]
4
回文自动机裸题。。。

对于每一个节点直接用NUM[i]*len[i]更新Ans,num的真实值为还要再用类似拓扑序的东西再统计一下

#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 300010
using namespace std;
typedef long long ll;
char s[MAXN];
int ch[MAXN][26],tot,len[MAXN],cnt[MAXN],fail[MAXN],now,n,rt,last;
ll ans;
 
 
int newnode(int x){
    len[tot]=x;
    return tot++;
}
 
inline int get_fail(int x,int n){
    while(s[n-len[x]-1]!=s[n])x=fail[x];
    return x;
}
 
int main(){
    gets(s+1);
    s[0]=-1;newnode(0);newnode(-1);
    fail[0]=1;
    for(n=1;s[n];n++){
        s[n]-='a';
        rt=get_fail(last,n);
        if(!ch[rt][s[n]]){
            now=newnode(len[rt]+2);
            fail[now]=ch[get_fail(fail[rt],n)][s[n]];
            ch[rt][s[n]]=now;
        }
        cnt[last=ch[rt][s[n]]]++;
    }
    for(int i=tot-1;i>0;i--)
        cnt[fail[i]]+=cnt[i],ans=max(ans,(ll)cnt[i]*(ll)len[i]);
        printf("%lld\n",ans);
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值