题目描述

输入

输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。

输出

输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。

样例输入

16
ggabaabaabaaball

样例输出

12

提示

N<=500000

题意就是要求找到一个最长的回文串满足它的一个回文后缀长度是它的一半,也就是在回文自动机的$fail$树上找到一个所代表的回文串的长度为$4$的倍数的点使它有一个祖先所代表的的回文串的长度是它的一半。直接$dfs$整棵$fail$树,用桶存一下长度为偶数的点即可。

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
char s[500010];
int fail[500010];
int tr[500010][26];
int len[500010];
int n,p,q;
int last;
int cnt[500010];
int head[500010];
int tot;
int num;
int to[500010];
int next[500010];
int ans;
void add(int x,int y)
{
next[++tot]=head[x];
head[x]=tot;
to[tot]=y;
}
int build(int x)
{
len[++num]=x;
return num;
}
int getfail(int x,int n)
{
while(s[n-len[x]-1]!=s[n])
{
x=fail[x];
}
return x;
}
void dfs(int x)
{
if(len[x]%2==0)
{
cnt[len[x]]++;
}
if(len[x]%4==0&&cnt[len[x]/2])
{
ans=max(ans,len[x]);
}
for(int i=head[x];i;i=next[i])
{
dfs(to[i]);
}
cnt[len[x]]--;
}
int main()
{
scanf("%d",&n);
scanf("%s",s+1);
s[0]=-1,fail[0]=1,last=0;
len[0]=0,len[1]=-1,num=1;
for(int i=1;i<=n;i++)
{
int x=s[i]-'a';
p=getfail(last,i);
if(!tr[p][x])
{
q=build(len[p]+2);
fail[q]=tr[getfail(fail[p],i)][x];
tr[p][x]=q;
}
last=tr[p][x];
}
for(int i=1;i<=num;i++)
{
add(fail[i],i);
}
dfs(0);
printf("%d",ans);
}

BZOJ2342[Shoi2011]双倍回文——回文自动机的更多相关文章

  1. BZOJ2342 Shoi2011 双倍回文 【Manacher】

    BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...

  2. BZOJ2342: [Shoi2011]双倍回文

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 923  Solved: 317[Submit][Status ...

  3. bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...

  4. BZOJ2342:[SHOI2011]双倍回文(Manacher)

    Description   Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输出文件只有一行,即:输入数据中字符串的最长 ...

  5. [BZOJ2342] [Shoi2011]双倍回文(manacher)

    传送门 manacher...... 先跑一边manacher是必须的 然后枚举双倍回文串的对称轴x 把这个双倍回文串分成4段,w wR w wR 发现,只有当 y <= x + p[x] / ...

  6. bzoj2342: [Shoi2011]双倍回文 pam

    题解:先建pam,然后在fail树上dfs,从上到下的链如果有当前长度最远回文串的一半,那么更新答案 //#pragma GCC optimize(2) //#pragma GCC optimize( ...

  7. 【BZOJ-2342】双倍回文 Manacher + 并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1799  Solved: 671[Submit][Statu ...

  8. 【BZOJ2342】双倍回文(回文树)

    [BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...

  9. 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...

随机推荐

  1. 【原创】自己动手写一个能操作redis的客户端

    引言 redis大家在项目中经常会使用到.官网也提供了多语言的客户端供大家操作redis,如下图所示 但是,大家有思考过,这些语言操作redis背后的原理么?其实,某些大神会说 只要按照redis的协 ...

  2. 传统前端工程使用 Vue 等框架重构的思路

    这段时间遇到类似的问题,第一反应便是使用 cli 搭建项目,但是细想一下立马否决了,原因如下: 工程量太大,猴年马月能重构完,此期间原项目还是没有任何变动(如果没人跟你一起同步修改之前老项目的话 无法 ...

  3. 朱晔的互联网架构实践心得S1E6:给飞机换引擎和安全意识十原则

    朱晔的互联网架构实践心得S1E6:给飞机换引擎和安全意识十原则 [下载本文PDF进行阅读] 本文有两个部分,先介绍一下给飞机换引擎这个事情我的一些经验,因为篇幅较短然后介绍一下安全意识方面的一些心得. ...

  4. Leetcode 101. Symmetric Tree(easy)

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For e ...

  5. Python-Django下载与基本命令

    1.下载Django: pip3 install django 2.创建一个django project django-admin.py startproject mysite 当前目录下会生成mys ...

  6. 通过Webstorm上传代码到Github、更新代码后同步到github及克隆github代码到本地的方法

    导读: Github做为IT爱好者分享代码的一个知名的平台,广受大家喜欢,那么我们平时该怎么将自己写的代码上传到github上面保存并且提供给其他人参考? 我想方法不外乎如下几个: 1.直接在gith ...

  7. elasticsearch数据输入和输出

    Elastcisearch 是分布式的 文档 存储.它能存储和检索复杂的数据结构–序列化成为JSON文档–以 实时 的方式. 换句话说,一旦一个文档被存储在 Elasticsearch 中,它就是可以 ...

  8. linux虚拟机桥接网络配置

    版权声明:经验之谈,不知能否换包辣条,另,转载请注明出处. https://blog.csdn.net/zhezhebie/article/details/75035997 前言:我是最小化安装cen ...

  9. PHP中友好的处理方式

    在使用PHP进行开发的时候,由于PHP是弱类型语言的特性,所以,偶尔会遇到一些意想不到的错误.规范我们的编程就变得尤为重要了.下面总结一下,我日常开发中的一些经验,可能有些地方不妥,还请多多斧正,指教 ...

  10. Python3练习题 018:打印星号菱形

    Python的内置方法 str.center(width [, fillchar]) 就能轻而易举打印出来:str即是数量不等的星号,width即是最大宽度(7个空格),默认填充字符fillchar就 ...