洛谷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. .net(2)

    11.interface是否可继承interface?abstract class 是否可实现interface 回答1:接口可以继承接口,而且可以继承多个接口,用“,”进行分割,接口不允许直接或间接 ...

  2. 【题解】Luogu P4091 [HEOI2016/TJOI2016]求和

    原题传送门 \[\begin{aligned} a n s &=\sum_{i=0}^{n} \sum_{j=0}^{i}\left\{\begin{array}{c}{i} \\ {j}\e ...

  3. Entity Framework Core今日所得:避免 IEnumerable 以及 IQueryable 陷阱

    避免 IEnumerable 以及 IQueryable 陷阱: IEnumerable示用Linq会先去数据库查询所有记录,然后再条件查询. IQueryable接口派生自IEnumerable,但 ...

  4. (原创)如何搭建PLC+上位机监控系统达到成本的最小化?

    以西门子PLC举例; 西门子PLC有几个型号:S7-200SMART,S7-1200,S7-300,S7-400,S7-1500,价格从低到高. 1个项目中要求的IO数量:600点的DI+DO,若干个 ...

  5. Wireshark教程之一:认识Wireshark界面

    1.下载与安装 官网地址:https://www.wireshark.org/ 官网下载地址:https://www.wireshark.org/#download 本文以windows环境为例来说明 ...

  6. sql server union与unionALL区别

    两种用法 一样, 查询字段类型需要一致 union 会自动去重 union all  不会去重 select name ,age from student union select name ,age ...

  7. logback配置和使用

    简介 logback是由log4j创始人设计的又一个开源日志组件.当前分成三个模块: logback-core是其它两个模块的基础模块. logback-classic是log4j的一个 改良版本.此 ...

  8. 504 Gateway Time-out ( Nginx + PHP ) 解决小计

    问题 最近有个项目,运算量比较大,服务器经常报 504 Gateway Time-out 解决方案 fastcgi_connect_timeout 默认值是 60 第一次尝试修改为 120 ,仍然报5 ...

  9. 《SAP微顾问和大数据 》公众号管理课程清单

    互联网商业模式创新 电子商务与传统企业转型 “一带一路”信息化:格局与对策 “一带一路”沿线国家主权信用及风险防范 大数据下的资源整合和知识共享 地产数字化改革的痛点与处方 携手共建“一带一路” 数字 ...

  10. 4.Javascript中实现继承的几种方法及其优缺点

    要搞懂JS继承,我们首先要理解原型链:每一个实例对象都有一个__proto__属性(隐式原型),在js内部用来查找原型链:每一个构造函数都有prototype属性(显示原型),用来显示修改对象的原型, ...