洛谷4287:双倍回文

前言:

题目描述:

  • 记字符串\(w\)的倒置为\(w^R\)。例如\((abcd)^R=dcba\)。
  • 如果一个字符串能够表示成\(ww^Rww^R\)的形式,责成他是一个双倍回文。
  • 给定一个字符串,求最长双倍回文子串长度。

输入描述:

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

输出描述:

  • 输出一个整数表示答案,如果不存在双倍回文子串,则输出0。

思路:

  • 回文自动机模板题:\(trans\)指针的使用。

    • \(trans\)指针:小于等于当前节点长度一半的最长回文后缀,求法和\(fail\)指针类似。
    • 当新建一个节点后,如果他的长度小于等于2,那么这个结点的\(trans\)指针指向他的\(fail\)节点。
    • 否则的话,我们从他的父亲的\(trans\)指针指向的节点开始跳\(fail\)指针。
    • 直到跳到某个结点所表示的回文串的两侧都能拓展这个字符且拓展后的长度小于等于当前节点长度的一半。
    • 那么新建节点的\(trans\)指针就指向该节点的儿子。
  • 考虑一个字符串满足双倍回文:
    • 当且仅当他的\(trans\)指针指向的节点所表示的回文串长度恰好是这个字符串长度的一半,并且这个\(trans\)指针指向的节点所表示的回文串长度为偶数。
    • 枚举每个节点,不停更新答案。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10; int cnt; //节点个数
int last; //上一个结点
int trie[maxn][30]; //字典树
int len[maxn]; //当前节点的回文串长度
int fail[maxn]; //当前节点的fail指针
int len_str; //字符串的长度
char s[maxn]; //原字符串
int trans[maxn]; //trans指针表示<=当前节点长度一半的最长回文后缀 inline int get_fail(int las, int i)
{
while(s[i - len[las] - 1] != s[i])
las = fail[las];
return las;
} void init()
{
cnt = 1, last = 0;
len[0] = 0, len[1] = -1;
fail[0] = 1, fail[1] = 0;
} void build_PAM()
{
for(int i = 1; i <= len_str; i++)
{
int p = get_fail(last, i);
if(!trie[p][s[i]-'a'])
{
len[++cnt] = len[p] + 2;
fail[cnt] = trie[get_fail(fail[p], i)][s[i]-'a'];
trie[p][s[i]-'a'] = cnt; ///------------顺带求出trans指针
if(len[cnt] <= 2) trans[cnt] = fail[cnt];
///这一题数据较水 博主在这里一开始cnt写的是p
///但是没有被卡掉
///如果他的长度<=2,那么当前节点的trans指向他的fail节点
else
{
int tmp= trans[p];
while((s[i - len[tmp] - 1] != s[i]) || (((len[tmp] + 2)<<1) > len[cnt]))
tmp = fail[tmp];
//开始跳fail指针
//直到跳到某一个节点所表示的回文串两侧都能拓展这个字符
//并且拓展后的长度小于等于当前节点长度的一半.
trans[cnt] = trie[tmp][s[i]-'a'];
}
///------------结束
}
last = trie[p][s[i]-'a'];
}
} int main()
{
scanf("%d", &len_str);
scanf("%s", s + 1); s[0] = '#';
init(); build_PAM();
int ans = 0;
for(int i = 2; i <= cnt; i++) //枚举所有的节点
if((len[trans[i]]<<1)==len[i] && len[trans[i]] % 2 == 0)
ans = max(ans, len[i]);
cout << ans << endl;
return 0;
}

luogu_4287:双倍回文的更多相关文章

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

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

  2. BZOJ 2342 双倍回文(manacher算法)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2342 题意:定义双倍回文串为:串的长度为4的倍数且串的前一半.后一半.串本身均是回文的. ...

  3. BZOJ2342: [Shoi2011]双倍回文

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

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

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

  5. [SHOI 2011]双倍回文

    Description 题库链接 记一个字符串为 \(X\) ,它的倒置为 \(X^R\) .现在给你一个长度为 \(n\) 的字符串 \(S\) ,询问其最长的形同 \(XX^RXX^R\) 的子串 ...

  6. [SHOI2011]双倍回文

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

  7. BZOJ2342[Shoi2011]双倍回文——回文自动机

    题目描述 输入 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. 输出 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文 ...

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

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

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

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

随机推荐

  1. Tomcat 路由请求的实现 Mapper

    在分析 Tomcat 实现之前,首先看一下 Servlet 规范是如何规定容器怎么把请求映射到一个 servlet.本文首发于(微信公众号:顿悟源码) 1. 使用 URL 路径 收到客户端请求后,容器 ...

  2. vim中常用折叠命令

    最常用3个折叠命令 .反复打开关闭折叠:za (意思就是,当光标处折叠处于打开状态,za关闭之,当光标处折叠关闭状态,打开之) .打开全部折叠:zR .关闭全部折叠:zM 小试折叠: :set fdm ...

  3. Java自学-数字与字符串 比较字符串

    Java 比较字符串 示例 1 : 是否是同一个对象 str1和str2的内容一定是一样的! 但是,并不是同一个字符串对象 package character; public class TestSt ...

  4. 看年薪50W的架构师如何手写一个SpringMVC框架

    前言 做 Java Web 开发的你,一定听说过SpringMVC的大名,作为现在运用最广泛的Java框架,它到目前为止依然保持着强大的活力和广泛的用户群. 本文介绍如何用eclipse一步一步搭建S ...

  5. git 从远程克隆代码并实现分支开发,合并分支,上传本地代码到远程

    首先确认你已经安装了git 1.克隆远程代码到本地的操作 git clone 地址   打开git操作命令行 鼠标右键点击        复制需要克隆的项目的地址类似下面的ssh     输入命令进行 ...

  6. Java 之 线程安全(线程同步)

    一.线程安全 当有多个线程同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,这就是线程安全的. 下面通过一个案例来演示线程的 ...

  7. windows mysql服务器

    安装完mysql服务器后,需要启动服务器, 才可提供数据库存储服务.windows上如何启动和关闭mysql服务器呢? 1. 启动 进入mysql的安装目录,如D:\Program Files\mys ...

  8. java web的转发与重定向

    java web的转发与重定向 原创 2012年12月15日 11:51:39 19312 转发和重定向的区别 一.使用方法 转发:request.getRequestDispatcher(" ...

  9. python之路第三天

    2018年 7月 13 日 while循环语句: 输出1-5的数 s = 1 whlie s < 6: print(s) 用while循环输入 1 2 3 4 5 6  8 9 10 while ...

  10. Mac 提示错误”xcrun: error“

    错误现象: Mac 安装python模块时出现异常错误 xcrun: error: invalid active developer path (/Library/Developer/CommandL ...