BZOJ3676:[APIO2014]回文串(SAM,Manacher)
Description
考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最 大出现值。
Input
输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。
Output
输出一个整数,为逝查回文子串的最大出现值。
Sample Input
abacaba
【样例输入2]
www
Sample Output
7
【样例输出2]
4
HINT
一个串是回文的,当且仅当它从左到右读和从右到左读完全一样。
在第一个样例中,回文子串有7个:a,b,c,aba,aca,bacab,abacaba,其中:
● a出现4次,其出现值为4:1:1=4
● b出现2次,其出现值为2:1:1=2
● c出现1次,其出现值为l:1:l=l
● aba出现2次,其出现值为2:1:3=6
● aca出现1次,其出现值为1=1:3=3
●bacab出现1次,其出现值为1:1:5=5
● abacaba出现1次,其出现值为1:1:7=7
故最大回文子串出现值为7。
【数据规模与评分】
数据满足1≤字符串长度≤300000。
Solution
垃圾题目卡$SAM+Manacher$做法的空间……害我把所有的结构体全拆开还把$SAM$的$son$数组换成了$map$才过……
首先众所周知,一个串的本质不同的回文子串只有$O(n)$级别,且在$Manacher$过程中右端点右移的情况就是本质不同的回文子串。所以我们可以做一遍$Manacher$把本质不同的回文子串求出来。
假设现在的一个回文子串是$S_{l,r}$,设$SAM$插入$r$的时候的$np$节点为$node_r$,那么我们知道,$S_{l,r}$一定是$node_r$代表的子串的一个后缀,且$S_{l,r}$的出现次数是$right_{node_r}$。
我们可以倍增从$node_r$往上跳,因为越往上跳$right$越大。跳到长度取值范围包括$r-l+1$的节点然后更新答案就可以了。
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#define N (600009)
#define LL long long
using namespace std; int to[N],nxt[N];
int n,m,pos[N],len[N];
int Depth[N],f[N][];
int head[N],num_edge;
int p,q,np,nq,last=,cnt=;
int fa[N],rig[N],step[N],node[N];
map<int,int>son[N];
LL ans;
char s[N>>],t[N]; void add(int u,int v)
{
to[++num_edge]=v;
nxt[num_edge]=head[u];
head[u]=num_edge;
} void Insert(int x)
{
p=last; np=last=++cnt; step[np]=step[p]+; rig[np]=;
while (!son[p][x] && p) son[p][x]=np, p=fa[p];
if (!p) fa[np]=;
else
{
q=son[p][x];
if (step[q]==step[p]+) fa[np]=q;
else
{
nq=++cnt; step[nq]=step[p]+;
son[nq]=son[q];
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
while (son[p][x]==q) son[p][x]=nq, p=fa[p];
}
}
} void DFS(int x,int fa)
{
Depth[x]=Depth[fa]+; f[x][]=fa;
for (int i=; i<=; ++i) f[x][i]=f[f[x][i-]][i-];
for (int i=head[x]; i; i=nxt[i])
DFS(to[i],x), rig[x]+=rig[to[i]];
} void Calc()
{
for (int i=; i<n; ++i) Insert(s[i]-'a'), node[i]=np;
for (int i=; i<=cnt; ++i) add(fa[i],i);
DFS(,);
} void Solve(int p,int k)
{
while (t[p+k]=='#' || t[p+k]==')') --k;
int x=node[pos[p+k]],y=pos[p+k]-pos[p-k]+;
for (int i=; i>=; --i) if (step[f[x][i]]>=y) x=f[x][i];
ans=max(ans,1ll*rig[x]*y);
} void Manacher()
{
t[++m]='(';
for (int i=; i<n; ++i) t[++m]='#', t[++m]=s[i], pos[m]=i;
t[++m]='#'; t[++m]=')'; int x,mid=,maxn=;
for (int i=; i<=m; ++i)
{
if (i>maxn) x=;
else x=min(maxn-i+,len[mid*-i]);
while (t[i+x]==t[i-x]) Solve(i,x), ++x;
len[i]=x;
if (i+x->maxn) maxn=i+x-, mid=i;
}
} int main()
{
scanf("%s",s); n=strlen(s);
Calc(); Manacher();
printf("%lld\n",ans);
}
BZOJ3676:[APIO2014]回文串(SAM,Manacher)的更多相关文章
- BZOJ3676 APIO2014回文串(manacher+后缀自动机)
由于本质不同的回文子串数量是O(n)的,考虑在对于每个回文子串在第一次找到它时对其暴力统计.可以发现manacher时若右端点移动则找到了一个新回文串.注意这样会漏掉串长为1的情况,特判一下. 现在问 ...
- bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增
bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- [BZOJ3676][APIO2014]回文串(Manacher+SAM)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3097 Solved: 1408[Submit][Statu ...
- [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3396 Solved: 1568[Submit][Statu ...
- BZOJ3676: [Apio2014]回文串(SAM+Manacher/PAM)
Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行 ...
- [bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增
Brief Description 一个回文串的value定义为这个回文串的长度乘以出现次数.给定一个字符串,求\(value_{max}\). Algorithm Design 我们使用Manach ...
- BZOJ3676 APIO2014 回文串 Manacher、SA
传送门 首先一个结论:串\(S\)中本质不同的回文串个数最多有\(|S|\)个 证明考虑以点\(i\)结尾的所有回文串,假设为\(S[l_1,i],S[l_2,i],...,S[l_k,i]\),其中 ...
- 2018.12.15 bzoj3676: [Apio2014]回文串(后缀自动机)
传送门 对原串建立一个后缀自动机,然后用反串在上面匹配. 如果当前匹配的区间[l,r][l,r][l,r]包裹了当前状态的endposendposendpos中的最大值,那么[l,maxpos][l, ...
随机推荐
- C#获取gif帧数
C#获取gif帧数 /// <summary> /// 获取gif帧数 /// </summary> /// <param name="gifBytes&quo ...
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
- VMware12创建新的虚拟机及设置硬件环境
一.安装VMware虚拟机 http://jingyan.baidu.com/article/215817f78879c21edb142379.html?qq-pf-to=pcqq.group 二.创 ...
- webhttpbinding、basichttpbinding和wshttpbinding的区别
webhttpbinding是REST风格的绑定,您只需点击一个URL,然后从Web服务中获取大量XML或JSON. basichttpbinding和wshttpbinding是两个基于SOAP的绑 ...
- Code Signal_练习题_digitDegree
Let's define digit degree of some positive integer as the number of times we need to replace this nu ...
- ss 重新设置 端口的方法 记录
1. 选择 ssh 进行远程登入: ssh root@服务器ip -p 端口, 事例如:ssh root@176.122.134.96 -p 28202 2. ls 展示 当前目录下的文件,看到有 s ...
- SSM(Spring MVC +Spring+Mybatis)整合——maven工程
所谓的SSM 其实就是Spring MVC下整合mybatis. 具体的定义网络上都有,很详细. 这里只说项目的搭建步骤. 第一步 新建maven工程 工程目录如下: 配置pom.xml文件,引入所需 ...
- html5的web存储与cookie的区别
以下从3个方面进行比较: 1,容量:cookie只有4KB,localStorage和sessionStorage最大容量5M 2,是否会携带到ajax中:cookie由每个对服务器的请求来传递,会影 ...
- 位图和SVG用法比较
位图,亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的.这些点可以进行不同的排列和染色以构成图样.当放大位图时,可以看见赖以构成整个图像的无数单个方块.扩大位图尺寸的效果是增大单个像素 ...
- Python 基于python实现的http接口自动化测试框架(含源码)
基于python实现的http+json协议接口自动化测试框架(含源码) by:授客 QQ:1033553122 欢迎加入软件性能测试交流 QQ群:7156436 由于篇幅问题,采用百度网 ...