题目描述

记字符串 w 的倒置为 wR 。例如 (abcd)R=dcba , (abba)R=abba 。

对字符串x,如果 x 满足 xR=x ,则称之为回文;例如abba是一个回文,而abed不是。

如果x能够写成的 wwRwwR 形式,则称它是一个“双倍回文”。换句话说,若要 x 是双倍回文,它的长度必须是 \(4\) 的倍数,而且 x , x 的前半部分, x 的后半部分都要是回文。例如 abbaabba 是一个双倍回文,而 abaaba 不是,因为它的长度不是4的倍数。

x 的子串是指在 x 中连续的一段字符所组成的字符串。例如 \(be\) 是 \(abed\) 的子串,而 \(ac\) 不是。

x 的回文子串,就是指满足回文性质的 x 的子串。

x 的双倍回文子串,就是指满足双倍回文性质的 x 的子串。

你的任务是,对于给定的字符串,计算它的最长双倍回文子串的长度。

输入输出格式

输入格式:

输入分为两行。

第一行为一个整数,表示字符串的长度。

第二行有个连续的小写的英文字符,表示字符串的内容。

输出格式:

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

输入输出样例

输入样例#1: 复制

16

ggabaabaabaaball

输出样例#1: 复制

12

说明

N \(\le\) 500000


题解

一道海星的回文树思维题。

其实wwRwwR要是回文串。

w=wR。所以其实就是先找出一个wwR,然后保存,然后看后面是否还能接着找到一个wwR。如果找到了就验证它们的长度能否被四整除就OK了。

当然我们又引进了一个新的数组half,这个数组表示以这个节点为回文串结尾,回文串中间的节点的位置。但是回文串自己本身并不保证一定让half成立。所以我们还需要在统计时验证一下答案是否合理。


代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int len;
char s[500050];
struct node{
int fail,len,ch[26],half;
}t[500050];
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
} void solve()
{
int k=0,tot=1;
t[1].fail=t[0].fail=1;t[1].len=-1;
for(int i=1;i<=len;i++)
{
while(s[i-t[k].len-1]!=s[i])k=t[k].fail;
if(!t[k].ch[s[i]-'a']){
t[++tot].len=t[k].len+2;
int j=t[k].fail;
while(s[i-t[j].len-1]!=s[i])j=t[j].fail;
t[tot].fail=t[j].ch[s[i]-'a'];
t[k].ch[s[i]-'a']=tot;
if(t[tot].len==1)t[tot].half=0;
else {
int pos=t[k].half;
while(s[i-t[pos].len-1]!=s[i]||(t[pos].len+2)*2>t[tot].len)
pos=t[pos].fail;
t[tot].half=t[pos].ch[s[i]-'a'];
}
}
k=t[k].ch[s[i]-'a'];
}
} int main()
{
scanf("%d%s",&len,s);
solve();
int ans=0;
for(int i=1;i<=len;i++)
if(t[i].len%4==0&&t[t[i].half].len*2==t[i].len)ans=max(ans,t[i].len);
cout<<ans<<endl;
return 0;
}

最新文章

  1. Linux 利用lsof命令恢复删除的文件
  2. PHP Warning: ob_start() : output handler &#39;ob_gzhandler conflicts with &#39;zlib output compression&#39;
  3. JS基础知识(-)
  4. opencv学习——兴趣区选取
  5. RMQ算法讲解
  6. 转:PHP分页技术的代码和示例
  7. ZOJ 1171 Sorting the Photos
  8. 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#39;groups)VALUES(&#39;1&#39;,&#39;hh&#39;,&#39;hh@163.com&#39;,&#39;Boss&#39;)&#39; at line 1
  9. 深入理解Linux内存分配
  10. 第7天【find命令、if语句、磁盘管理、文件系统管理】
  11. bootstrap 模态框事件
  12. wince sqlite c#
  13. Pytorch 之 backward
  14. HTML5:基本语句
  15. 动态规划之97 Interleaving String
  16. 并发编程:IO多路复用。
  17. ArduinoYun教程之Arduino编程环境搭建
  18. Linux内存管理-高端内存(二)
  19. 【Sklearn系列】KNN算法
  20. 1-spring xml 和 注解 解析过程

热门文章

  1. jqGrid收藏的链接
  2. 关闭WPS屏保
  3. split(&quot;:&quot;)[0].substring(1)
  4. 【原创】apache虚拟主机配置
  5. Sublime使用随记
  6. OpenGL编程(六)通过三角形绘画出3D模型
  7. CF 286(div 2) B Mr. Kitayuta&#39;s Colorful Graph【传递闭包】
  8. rsyslog 存储到 mysql
  9. “.”开头,以&quot;}&quot;结尾,中间是任意字符的正则
  10. How Javascript works (Javascript工作原理) (九) 网页消息推送通知机制