BZOJ3676 APIO2014回文串(manacher+后缀自动机)
由于本质不同的回文子串数量是O(n)的,考虑在对于每个回文子串在第一次找到它时对其暴力统计。可以发现manacher时若右端点移动则找到了一个新回文串。注意这样会漏掉串长为1的情况,特判一下。
现在问题变为统计一个子串的出现次数。可以用SA,二分乱搞一下即可。这里使用SAM。以parent树上表示该子串的节点为起点,用倍增往上跳,找到深度最小的满足len限制的点就好了,出现次数就是其right集合的大小。
uojAC,luoguRE一个点,bzojMLE……
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 600010
int n,last,cnt,len[N],fail[N],son[N][],size[N],pos[N>>],p[N];
long long ans=;
char s[N];
namespace tree
{
int p[N],t=,fa[N][];
struct data{int to,nxt;
}edge[N];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k)
{
for (int i=p[k];i;i=edge[i].nxt)
{
fa[edge[i].to][]=k;
dfs(edge[i].to);
size[k]+=size[edge[i].to];
}
}
void build()
{
for (int i=;i<=cnt;i++) addedge(fail[i],i);
fa[][]=;dfs();
for (int j=;j<;j++)
for (int i=;i<=cnt;i++)
fa[i][j]=fa[fa[i][j-]][j-];
}
int calc(int l,int r)
{
int x=pos[r];
for (int j=;~j;j--) if (len[fa[x][j]]>=r-l+) x=fa[x][j];
return size[x];
}
}
using tree::calc;
void ins(int c,int n)
{
int x=++cnt,p=last;last=x;len[x]=n;size[x]=;pos[n]=x;
while (!son[p][c]&&p) son[p][c]=x,p=fail[p];
if (!p) fail[x]=;
else
{
int q=son[p][c];
if (len[p]+==len[q]) fail[x]=q;
else
{
int y=++cnt;len[y]=len[p]+;
memcpy(son[y],son[q],sizeof(son[q]));
fail[y]=fail[q];fail[q]=fail[x]=y;
while (son[p][c]==q) son[p][c]=y,p=fail[p];
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3676.in","r",stdin);
freopen("bzoj3676.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
last=cnt=;
scanf("%s",s+);n=strlen(s+);
for (int i=;i<=n;i++) ins(s[i]-,i);
tree::build();
for (int i=n;i>=;i--) s[i*-]=s[i];
for (int i=;i<n;i++) s[i<<]='$';
int x=;
for (int i=;i<=n;i++) ans=max(ans,1ll*calc(i,i));
for (int i=;i<n*;i++)
{
if (x+p[x]>i) p[i]=min(x+p[x]-i,p[x-(i-x)]);
while (i-p[i]->=&&i+p[i]+<n*&&s[i+p[i]+]==s[i-p[i]-])
{
p[i]++;
if (s[i+p[i]]!='$') ans=max(ans,1ll*((i+p[i]>>)-(i-p[i]>>)+)*calc((i-p[i]>>)+,(i+p[i]>>)+));
}
if (i+p[i]>x+p[x]) x=i;
}
cout<<ans;
return ;
}
BZOJ3676 APIO2014回文串(manacher+后缀自动机)的更多相关文章
- [bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增
Brief Description 一个回文串的value定义为这个回文串的长度乘以出现次数.给定一个字符串,求\(value_{max}\). Algorithm Design 我们使用Manach ...
- [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3396 Solved: 1568[Submit][Statu ...
- 2018.12.15 bzoj3676: [Apio2014]回文串(后缀自动机)
传送门 对原串建立一个后缀自动机,然后用反串在上面匹配. 如果当前匹配的区间[l,r][l,r][l,r]包裹了当前状态的endposendposendpos中的最大值,那么[l,maxpos][l, ...
- [BZOJ3676][APIO2014]回文串(Manacher+SAM)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3097 Solved: 1408[Submit][Statu ...
- BZOJ3676 APIO2014 回文串 Manacher、SA
传送门 首先一个结论:串\(S\)中本质不同的回文串个数最多有\(|S|\)个 证明考虑以点\(i\)结尾的所有回文串,假设为\(S[l_1,i],S[l_2,i],...,S[l_k,i]\),其中 ...
- [APIO2014]回文串 manacher 后缀数组
题面:洛谷 题解: 还是这个性质:对于每个串而言,本质不同的回文串最多只有O(n)个. 所以我们先求出这O(n)个本质不同的回文串,然后对整个串求一次sa. 然后对于每个回文串,求出它的出现次数,更新 ...
- bzoj 3676: [Apio2014]回文串【后缀自动机+manacher】
用manacher找出本质不同的回文子串放在SAM上跑 #include<iostream> #include<cstdio> #include<cstring> ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增
bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...
随机推荐
- 在模拟器上运行Android项目时报错:DELETE_FAILED_INTERNAL_ERROR Error while Installing APKs
今天在Android Studio自带的模拟器上运行项目的时候,出现如下所示Error:当点击ok后,发现模拟器不能运行程序. 解决办法: 更改Android Studio中的设置: File---& ...
- (推荐)Skyline调用WMTS服务接口
文章地址 http://blog.csdn.net/chaiqi/article/details/9302373 供大家学习参考.
- openssl生成签名与验证签名
继上一篇RSA对传输信息进行加密解密,再写个生成签名和验证签名. 一般,安全考虑,比如接入支付平台时,请求方和接收方要互相验证是否是你,就用签名来看. 签名方式一般两种,对称加密和非对称加密.对称加密 ...
- odoo中的ORM操作
ORM方法简介 OpenERP的关键组件, ORM是一个完整的对象关系映射层,是开发人员不必编写基本的SQL管道. 业务对象被声明继承字models.Models的python类. 这让业务对象在OR ...
- JVM调优-GC参数
一.Throughput收集器(吞吐量)-XX:+UseParallelGC-XX:+UseParallelOldGC *参数调整:通过调整堆大小,减少GC停顿时间,增大吞吐量增强堆大小可以减少Ful ...
- Spring Aop: 关于继承和execution target this @annotation
1.多态 target指通过这个对象调用的方法 (匹配标识对象的所有方法) getMethod() this指调用这个对象的方法 (匹配标识对象实现的方法) getDeclaredMethod( ...
- [Python]Practice makes perfect
Practice makes perfect 发音被儿子鄙视了.需要加强练习 以此自勉.
- Nginx支持WebSocket反向代理-学习小结
WebSocket是目前比较成熟的技术了,WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择.其为HTML5的一部分,WebSocket相较于原来开发这类app的 ...
- Redis主从复制原理总结
和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redi ...
- Python练习-8
1,复习 ascii:字母,数字,特殊字符:1个字节,8位 Unicode:16位 两个字节 升级 32 位 四个字节 utf-8:最少一个字节 8位表示. 英文字母 8位 1个字节 欧洲16位,2个 ...