解题:APIO 2014 回文串
初见SAM
洛谷数据太弱了,我SAM写错了居然有90pts=。=???
SAM求一个子串$(l,r)$的出现次数:从右端点对应状态开始在parent树上倍增,当目标节点的$len$大于等于子串长度时就往上跳,最后所在节点的$len$就是该串的出现次数
于是边$manacher$边在SAM上统计当前串的出现次数即可,复杂度$O(n\log n)$,注意边界
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,K=;
int p[N],noww[N],goal[N];
int rnk[N],bkt[N],mul[N][K];
int trs[N][],fth[N],len[N],siz[N],num[N];
char str[N>>],Str[N];
int lth,lst,cnt,tot,mid,maxr;
long long ans;
void link(int f,int t)
{
noww[++cnt]=p[f];
goal[cnt]=t,p[f]=cnt;
}
void DFS(int nde,int fth)
{
mul[nde][]=fth;
for(int i=p[nde];i;i=noww[i])
DFS(goal[i],nde),siz[nde]+=siz[goal[i]];
for(int i=;mul[nde][i];i++)
mul[nde][i]=mul[mul[nde][i-]][i-];
}
void Insert(int ch,int ps)
{
int nde=lst,newn=++tot;
num[ps]=lst=newn,siz[newn]=,len[newn]=len[nde]+;
while(nde&&!trs[nde][ch])
trs[nde][ch]=newn,nde=fth[nde];
if(!nde) fth[newn]=;
else
{
int tran=trs[nde][ch];
if(len[tran]==len[nde]+)
fth[newn]=tran;
else
{
int rnde=++tot; len[rnde]=len[nde]+;
for(int i=;i<=;i++) trs[rnde][i]=trs[tran][i];
fth[rnde]=fth[tran],fth[tran]=fth[newn]=rnde;
while(nde&&trs[nde][ch]==tran)
trs[nde][ch]=rnde,nde=fth[nde];
}
}
}
void prework()
{
register int i,j;
scanf("%s",str+),lth=strlen(str+),lst=tot=;
for(i=;i<=lth;i++) Insert(str[i]-'a',i);
for(i=;i<=tot;i++) link(fth[i],i); DFS(,);
}
void Solve(int l,int r)
{
l=(l+l%)/,r=(r-r%)/;
if(l>r) return ;
int nde=num[r],lth=r-l+;
for(int i=;~i;i--)
if(lth<=len[mul[nde][i]])
nde=mul[nde][i];
ans=max(ans,1ll*lth*siz[nde]);
}
void Manacher()
{
register int i;
int newl=*lth+;
for(i=;i<=newl;i++)
Str[i]=(i&)?'?':str[i>>];
Str[]='>',Str[newl+]='<';
for(i=;i<=newl;i++)
{
fth[i]=(maxr>=i)?min(maxr-i+,fth[*mid-i]):;
Solve(i-fth[i]+,i+fth[i]-);
while(Str[i-fth[i]]==Str[i+fth[i]])
fth[i]++,Solve(i-fth[i]+,i+fth[i]-);
if(i+fth[i]->maxr) maxr=i+fth[i]-,mid=i;
}
}
int main()
{
prework(),Manacher();
printf("%lld",ans);
return ;
}
解题:APIO 2014 回文串的更多相关文章
- APIO 2014 回文串(Manacher+后缀自动机+倍增)
题意 https://www.lydsy.com/JudgeOnline/problem.php?id=3676 思路 好像还是回文自动机裸体,但是 \(\text{Manacher}\) +后缀自动 ...
- 【题解】回文串 APIO 2014 BZOJ 3676 COGS 1985 Manacher+后缀数组+二分
这题可以用回文自动机来做,但是我并没有学,于是用Manacher+SA的做法O(nlogn)水过 首先,看到回文串就能想到用Manacher 同样还是要利用Manacher能不重复不遗漏地枚举每个回文 ...
- leetcode 214. 最短回文串 解题报告
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串. 示例 1: 输入: "aacecaaa" 输出: "aaa ...
- 洛谷 P4555 [国家集训队]最长双回文串 解题报告
P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...
- lintcode :Valid Palindrome 有效回文串
题目: 有效回文串 给定一个字符串,判断其是否为一个回文串.只包含字母和数字,忽略大小写. 样例 "A man, a plan, a canal: Panama" 是一个回文. & ...
- lintcode:Palindrome Partitioning 分割回文串
题目: 分割回文串 给定一个字符串s,将s分割成一些子串,使每个子串都是回文串. 返回s所有可能的回文串分割方案. 样例 给出 s = "aab",返回 [ ["aa&q ...
- 动态规划——H 最少回文串
We say a sequence of characters is a palindrome if it is the same written forwards and backwards. Fo ...
- 动态规划——G 回文串
G - 回文串 Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- 小白月赛13 B小A的回文串 (马拉车算法求最长回文子串)
链接:https://ac.nowcoder.com/acm/contest/549/B来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
随机推荐
- docker基本的常用命令
- CentOS 7.2二进制安装mysql-5.7.19
官方文档地址:https://dev.mysql.com/doc/refman/5.7/en/binary-installation.html 开始安装 1.下载mysql二进制包 # cd /usr ...
- NES像素风格的Raspberry
周末小实践,vue+树莓派+一言API 一直有个想法,让树莓派做后端,实现一个有趣的网络服务.可是,苦于不会前端,迟迟无法动手.最近由于工作任务需要研究了一下前端. 问过前端大佬们,个个都说你得用vu ...
- Mybatis-Plus的填坑之路 - Lynwood/wunian7yulian
目录 Mybatis-Plus 我来填坑~ 目录 一.简单介绍 官方说明 : 成绩: 最新版本: 开发层面MyBatis-Plus特色 Mybatis-Plus中的Plus 二.MP的特性 三.MP框 ...
- 【转】PHPCMS v9 自定义表单添加验证码验证
1. 在 \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=&quo ...
- Python学习之web框架 Flask
一.通过PIP 安装Flask 1.1 Windows环境安装pip A.首先PIP进入官网(https://pypi.python.org/pypi/pip)下载gz包 B.对gz压缩包进行解压,解 ...
- Pearson Distance
Pearson Distance: where: 1. is the covariance 2. is the standard deviation of 3. is the standard ...
- Python 装饰器Decorator(二)
对于上一篇“”Python闭包“”随笔中提到的make_averager()函数的如下实现,我们把历史值保存在列表里,每次计算平均值都需要重新求和,当历史值较多时,需要占用比较多的空间并且效率也不高. ...
- 王者荣耀交流协会--第2次Scrum会议
Scrum master:袁玥 要求1:工作照片 要求2:时间跨度:2017年10月14号 6:02--6:43 共计41min 要求3:地点:一食堂二楼两张桌子旁(靠近卖方便面那边) 要求4:立 ...
- 元素相加交换另解&puts的一个用法
#include<iostream> using namespace std; int main(){ int a,b; cin>>a>>b; a^=b; b^=a ...