ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3649-[APIO2014]回文串【PAM】

2021-01-09 09:01:05  阅读:195  来源: 互联网

标签:ch SAM P3649 int text APIO2014 fail PAM


正题

题目链接:https://www.luogu.com.cn/problem/P3649


题目大意

一个字符串,求最大的回文串长度×出现次数


解题思路

构建出 PAM \text{PAM} PAM然后统计一下每个节点作为后缀的次数, f a i l fail fail树上上传一下信息就好了,时间复杂度 O ( n ) O(n) O(n)。

当然也可以 SAM + Manacher + \text{SAM}+\text{Manacher}+ SAM+Manacher+倍增,因为一个字符串里本质不同的回文串就是会让马拉车的 m a x r i g h t maxright maxright增加的回文串,这些最多只有 n n n个,马拉车跑出来的丢到 SAM \text{SAM} SAM倍增找到对应节点即可。时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

这里写的是 PAM \text{PAM} PAM


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e5+10;
int n,tot,fail[N],len[N],cnt[N],ch[N][26];
char s[N];long long ans;
int get_fail(int x,int n){
    for(;s[n-len[x]-1]!=s[n];)x=fail[x];
    return x;
}
int Insert(int n,int x){
    x=get_fail(x,n);
    int c=s[n]-'a';
    if(!ch[x][c]){
        len[++tot]=len[x]+2;
        int y=get_fail(fail[x],n);
        fail[tot]=ch[y][c];
        ch[x][c]=tot;
    }
    cnt[ch[x][c]]++;
    return ch[x][c];
}
int main()
{
    scanf("%s",s+1);n=strlen(s+1);
    int last=0;len[1]=-1;fail[0]=tot=1;
    for(int i=1;i<=n;i++)
        last=Insert(i,last);
    for(int i=tot;i>=1;i--)
        cnt[fail[i]]+=cnt[i];
    for(int i=1;i<=tot;i++)
        ans=max(ans,1ll*len[i]*cnt[i]);
    printf("%lld\n",ans);
}

标签:ch,SAM,P3649,int,text,APIO2014,fail,PAM
来源: https://blog.csdn.net/Mr_wuyongcong/article/details/112387403

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有