【BZOJ3676&UOJ103】回文串(manacher,Trie)
题意:考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出现值”为t在s中的出现次数乘以t的长度。
请你求出s的所有回文子串中的最大出现值。
len<=300000
思路:
做法一:manacher+Trie
鸣谢UOJ上ID为nothing100的小哥(小姐姐?)
学P一时爽,转C火葬场
考虑不同的回文子串中间也是有子串关系的,并且互不包含的极长回文子串的数量是O(n)级别的
所以可先用manacher算出每个位置的最长回文半径
将它们表示成一棵树的形状,一个节点的儿子是它所代表的子串向两侧扩展一个相同字母的串
判断是否是父子关系可以用hash
最后dfs一遍求子树大小就行了,注意需要双hash,C党hash后可以用map和makepair
讲道理C党到这里就能做了,问题我是P党
考虑到刚才那棵树,如果你每个串都只取后半段,那么它是一颗Trie树
所以可以用和刚才类似的方法,而且并不需要hash
manacher过程中
i关于id的对称中心j,mx>i时:
如果p[j]>mx-i则p[i]需要从p[j]开始退格,依次删除最后一个字符直到到达mx-i为止
否则p[i]即为p[j]
mx<=i时说明当前只有i一个字符,就从头开始扩展
UOJ上过了,BZ上没过,残念……
var map:array[..,..]of longint;
fa,size,p,f,a,h:array[..]of longint;
n,m,i,j,mx,id,cnt,len:longint;
ans:int64;
ch:char; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; function max(x,y:int64):int64;
begin
if x>y then exit(x);
exit(y);
end; function get(x,y:longint):longint;
begin
if map[x,y]= then
begin
inc(cnt);
fa[cnt]:=x;
map[x,y]:=cnt;
end;
exit(map[x,y]);
end; procedure dfs(u,ch:longint;dep:int64);
var i,v:longint;
begin
for i:= to do
begin
v:=map[u,i];
if v> then
begin
dfs(v,i,dep+);
size[u]:=size[u]+size[v];
end;
end;
if ch< then ans:=max(ans,dep*size[u]);
end; begin
assign(input,'bzoj3676.in'); reset(input);
assign(output,'bzoj3676.out'); rewrite(output); n:=; a[]:=; a[]:=;
while not eoln do
begin
read(ch);
inc(n); a[n]:=ord(ch)-ord('a')+;
inc(n); a[n]:=;
end;
inc(n); a[n]:=;
mx:=; id:=; cnt:=;
for i:= to n- do
begin
if mx>i then
begin
p[i]:=p[id*-i]; h[i]:=h[id*-i];
if p[i]>mx-i then
begin
for j:=p[i]- downto mx-i do h[i]:=fa[h[i]];
p[i]:=mx-i;
end;
end
else
begin
h[i]:=get(,a[i]);
p[i]:=;
end;
while a[i-p[i]]=a[i+p[i]] do
begin
h[i]:=get(h[i],a[i-p[i]]);
inc(p[i]);
end;
if p[i]+i>mx then
begin
mx:=p[i]+i; id:=i;
end;
inc(size[h[i]]);
end;
dfs(,,);
writeln(ans);
close(input);
close(output);
end.
做法2:回文自动机板子
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,int>P;
#define N 300010
#define M 210000
#define fi first
#define se second
#define MP make_pair
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const int MOD=,inv2=(MOD+)/;
double eps=1e-;
int INF=<<;
ll inf=5e13;
int dx[]={-,,,};
int dy[]={,,-,}; char s[N];
int n; struct pam
{
int q,p,id,cnt[N],num[N],f[N],len[N],t[N][]; pam()
{
id=; f[]=f[]=; len[]=-;
} void add(int x,int n)
{
while(s[n-len[p]-]!=s[n]) p=f[p];
if(!t[p][x])
{
int q=++id,k=f[p];
len[q]=len[p]+;
while(s[n-len[k]-]!=s[n]) k=f[k];
f[q]=t[k][x];
t[p][x]=q;
num[q]=num[f[q]]+;
}
p=t[p][x];
cnt[p]++;
} void solve()
{
ll ans=;
per(i,id,)
{
cnt[f[i]]+=cnt[i];
ans=max(ans,1ll*cnt[i]*len[i]);
}
printf("%lld\n",ans);
} }pam; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int main()
{
//freopen("1.in","r",stdin); scanf("%s",s+);
n=strlen(s+);
rep(i,,n) pam.add(s[i]-'a',i);
pam.solve();
return ;
}
【BZOJ3676&UOJ103】回文串(manacher,Trie)的更多相关文章
- BZOJ3676 APIO2014 回文串 Manacher、SA
传送门 首先一个结论:串\(S\)中本质不同的回文串个数最多有\(|S|\)个 证明考虑以点\(i\)结尾的所有回文串,假设为\(S[l_1,i],S[l_2,i],...,S[l_k,i]\),其中 ...
- [BZOJ3676][APIO2014]回文串(Manacher+SAM)
3676: [Apio2014]回文串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 3097 Solved: 1408[Submit][Statu ...
- [bzoj3676][Apio2014]回文串——Manacher+后缀自动机+倍增
Brief Description 一个回文串的value定义为这个回文串的长度乘以出现次数.给定一个字符串,求\(value_{max}\). Algorithm Design 我们使用Manach ...
- [APIO2014] [Uoj103] [Bzoj3676] Palindromes回文串 [Manacher,后缀数组]
用Manacher算法枚举回文子串,每次在后缀数组排序后的后缀数组中二分,因为用某一后缀和其他子串分别求匹配的长度,匹配长度在排序后该后缀的两侧具有单调性(匹配长度为min{H[x]|i<=x& ...
- bzoj3676 [Apio2014]回文串 卡常+SAM+树上倍增
bzoj3676 [Apio2014]回文串 SAM+树上倍增 链接 bzoj luogu 思路 根据manacher可以知道,每次暴力扩展才有可能出现新的回文串. 所以推出本质不同的回文串个数是O( ...
- [模板] 回文树/回文自动机 && BZOJ3676:[Apio2014]回文串
回文树/回文自动机 放链接: 回文树或者回文自动机,及相关例题 - F.W.Nietzsche - 博客园 状态数的线性证明 并没有看懂上面的证明,所以自己脑补了一个... 引理: 每一个回文串都是字 ...
- BZOJ3676 APIO2014回文串(manacher+后缀自动机)
由于本质不同的回文子串数量是O(n)的,考虑在对于每个回文子串在第一次找到它时对其暴力统计.可以发现manacher时若右端点移动则找到了一个新回文串.注意这样会漏掉串长为1的情况,特判一下. 现在问 ...
- BZOJ3676: [Apio2014]回文串(SAM+Manacher/PAM)
Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行 ...
- 【回文串-Manacher】
Manacher算法能够在O(N)的时间复杂度内得到一个字符串以任意位置为中心的回文子串.其算法的基本原理就是利用已知回文串的左半部分来推导右半部分. 转:http://blog.sina.com.c ...
- BZOJ 2342 回文串-Manacher
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2342 思路:先跑一遍Manacher求出p[i]为每个位置为中心的回文半径,因为双倍回文串 ...
随机推荐
- Hexo 添加Live2D看板娘
title: Hexo 添加 Live2D看板娘 二次元什么的最喜欢了[大好きです] 准备 项目地址 live2d模型 部分模型预览 开始 首先进入Hexo博客根目录安装live2d插件 $ npm ...
- 题解报告:hdu 1010 Tempter of the Bone
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 Problem Description The doggie found a bone in a ...
- 为WebSphere Application Server v8.5安装并配置JDK7
IBM WebSphere Application Server v8.5可以同时支持不同版本的JDK共存,并且可以通过命令设置概要文件所使用的JDK版本.WAS8.5默认安装JDK6,如果要使用JD ...
- java 对readLine扩展添加行号样式
java 的流的使用中,在字符缓冲输入流中,有一个每次读取一行数据的方法:readLine(): 在这里使用简单的继承方法对其继续扩展,使得返回每行前面添加序号 //需要导入的一些包 import j ...
- mysql timeout expired处理
一.发现问题 二.分析问题 .net长时间连接mysql导致超时: 方式一:连接用完后,就关闭连接 方式二:增加C#的执行sqlcommand时间 三.解决问题 增加了这一句,问题解决了 using ...
- PostgreSQL 流复制+高可用
QA PgPool-II 同步 Postgresql X1 服务器准备 192.168.59.121 PostgreSQL10 192.168.59.120 PGPool-II 3.7 X2 安装Po ...
- [ CodeForces 1065 B ] Vasya and Isolated Vertices
\(\\\) \(Description\) 求一个\(N\)个点\(M\)条边的无向图,点度为 \(0\) 的点最多和最少的数量. \(N\le 10^5,M\le \frac {N\times ( ...
- Tomcat无法clean,无法remove部署的项目
错误: 对部署在Tomcat下的项目进行clean操作,总是提示Could not load the Tomcat server configuration,错误信息如图: 解决: 原来是将Serve ...
- spark查看stage和tasks信息
spark提供了web-ui接口.外部命令等多种方法监视spark程序的执行状态.利用spark的监视功能,可以方便的查看spark应用程序执行的状态,具体包括:1)stage和tasks列表信息 ...
- parsley之验证属性设置
parsley.js添加表单验证功能,直接在html元素中添加对应属性: Name API Description Required #2.0必填 required HTML5 data-parsle ...