题目描述

输入

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

输出

输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出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. 这20个Docker Command,有几个是你会的?

    在这之前呢,也写过两篇关于Docker基础入门类的文章 Docker容器技术入门(一) Docker容器技术入门(二) 很多人都感觉这文章这么简单.这么基础,可是别忘记了"万丈高楼平地起&q ...

  2. Linux Namespace : 简介

    在初步的了解 docker 后,笔者期望通过理解 docker 背后的技术原理来深入的学习和使用 docker,接下来的几篇文章简单的介绍下 linux namespace 的概念以及基本用法. na ...

  3. 网络应用简记(4):DNS使用

    dns,domain name system,域名系统,把域名转化成ip的系统. 先来看几上工具的使用,这几个工具都能把域名转换成ip,都使用了dns.dns就好比数据库,通过对它的查询,能给url找 ...

  4. Requests爬虫

    一.request入门 之前写过一个urllib的爬虫方法,这个库是python内建的,从那篇文章也可以看到,使用起来很繁琐.现在更流行的一个爬虫库就是requests,他是基于urllib3封装的, ...

  5. Java 小记 - 时间的处理与探究

    前言 时间的处理与日期的格式转换几乎是所有应用的基础职能之一,几乎所有的语言都会为其提供基础类库.作为曾经 .NET 的重度使用者,赖其优雅的语法,特别是可扩展方法这个神级特性的存在,我几乎没有特意关 ...

  6. 重装mysql后导致Navicat连接失败

    今天重装了mysql数据库,然后再使用navicat去连接数据库的时候,一直报错 1251 Client does not support authentication protocol reques ...

  7. Python_每日习题_0003_完全平方数

    # 题目 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? # 程序分析 因为168对于指数爆炸来说实在太小了,所以可以直接省略数学分析,用最朴素的方法来获取 ...

  8. iRate---一个跳转AppStore评分弹窗

    https://www.aliyun.com/jiaocheng/357479.html 摘要:gitHub地址:https://github.com/nicklockwood/iRate可以通过配置 ...

  9. rest framwork 小试身手

    models.py from django.db import models class Course(models.Model): """ 课程表 "&quo ...

  10. asp.net core认证和授权的初始认识--claim、claimsidentity、claimsprincipal

    Claim表示一个声明单元,它用来组成ClaimsIdentity.ClaimsIdentity表示一个证件,例如身份证,身份证上面的名字表示一个Claim,身份证号也表示一个Claim,所有这些Cl ...