P3649-[APIO2014]回文串【PAM】
2024-09-07 07:30:33
正题
题目链接:https://www.luogu.com.cn/problem/P3649
题目大意
一个字符串,求最大的回文串长度×出现次数
解题思路
构建出\(\text{PAM}\)然后统计一下每个节点作为后缀的次数,\(fail\)树上上传一下信息就好了,时间复杂度\(O(n)\)。
当然也可以\(\text{SAM}+\text{Manacher}+\)倍增,因为一个字符串里本质不同的回文串就是会让马拉车的\(maxright\)增加的回文串,这些最多只有\(n\)个,马拉车跑出来的丢到\(\text{SAM}\)倍增找到对应节点即可。时间复杂度\(O(n\log n)\)
这里写的是\(\text{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);
}
最新文章
- Windows on Device 项目实践 2 - 感光灯制作
- Outlook不能预览和打开Excel文件:
- webapp中的meta
- MVC中Razor的使用 及路径问题
- Jsp内置对象及EL表达式的使用
- Is it possible to configure PostgreSQL to automatically close idle connections?
- delphi NativeXml的中文支持 乱码
- C#整理1——进制转换
- Html页面操作json串
- oracle如何导出和导入数据库表
- ARP攻击之Kali Linux局域网断网攻击
- Hystrix源码解析
- Linux中查看你的用户是否为root用户
- Android为ViewPager添加切换动画——自己定义ViewPager
- thymeleaf从session中获取数据
- 019PHP基础知识——函数(二)
- (Windows Maven项目)Redis数据库的安装和操作实现
- ELK之elasticsearch5.6的安装和head插件的安装
- 10 华电内部文档搜索系统 search03
- query 获取本身的HTML