P4287 [SHOI2011]双倍回文(回文树)
题目描述
记字符串 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;
}
P4287 [SHOI2011]双倍回文(回文树)的更多相关文章
- Manacher || BZOJ 2342: [Shoi2011]双倍回文 || Luogu P4287 [SHOI2011]双倍回文
题面:[SHOI2011]双倍回文 题解:具体实现时,就是在更新mr时维护前半段是回文串的最长回文串就好了 正确性的话,因为到i时如果i+RL[i]-1<=mr,那么答案肯定在i之前就维护过了: ...
- 洛谷 P4287 [SHOI2011]双倍回文题解
前言 用了一种很奇怪的方法来解,即二分判断回文,再进行某些奇怪的优化.因为这个方法很奇怪,所以希望如果有问题能够 hack 一下. 题解 我们发现,这题中要求的是字符串 \(SS'SS'\),其中 \ ...
- 洛谷P4287 [SHOI2011]双倍回文(回文自动机)
传送门 听说有大佬用manacher$O(n)$过此题……太强啦…… 说一下PAM的做法吧.(看了题解之后发现)蛮简单的 我们肯定要先建出回文自动机的 然后如果是枚举每一个节点暴跳fail指针肯定得T ...
- P4287 [SHOI2011]双倍回文
题意 考虑对每个节点\(x\)维护\(lastpos_x\)表示\(x\)的所有后缀回文串中第一个\(len\leqslant len_x/2\)并且能和\(x\)最后一个字符匹配的,之后枚举节点,判 ...
- BZOJ2342: [Shoi2011]双倍回文
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 923 Solved: 317[Submit][Status ...
- 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- [SHOI2011]双倍回文 manacher
题面: 洛谷:[SHOI2011]双倍回文‘ 题解: 首先有一个性质,本质不同的回文串最多O(n)个. 所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间 ...
- bzoj 2342: [Shoi2011]双倍回文 -- manacher
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符 ...
随机推荐
- 如何用一个app操作另外一个app.比如微信群控那样的
如何实现一个app.控制另外的app,比如市面上群控微信的,是用测试工具的原理?还是什么模拟点击的原理? 如何用一个app操作另外一个app.比如微信群控那样的 >> android这个答 ...
- windows共享如何重新登录,或用另外的用户登录
使用net use * /del 可以结束已有的所有连接,或net use \\192.168.1.10 /del可以结束指定连接.比如想重新登录共享的话,就用这个命令结束原来的连接,就可以重新登录 ...
- 在javascript中对于this指向的再次理解
总所周知,function () {}函数体内的this对象指向的是调用该函数的对象,那么我们看一下这个例子 <script> var length = 3; function fn () ...
- LeetCode Golang实现 1. 两数之和
1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这 ...
- /www: target is busy. 解决卸载磁盘目录繁忙的问题
umount /www 卸载磁盘遇到 以下问题 umount: /www: target is busy. (In some cases useful info about processes tha ...
- LCT复习
LCT,虚实链剖分.支持连边和断边操作.Tarjan制造. [HNOI2010]弹飞绵羊 当然这题分块可以做,常数小,但是LCT更无脑. 建立一个虚拟的弹飞节点\(n+1\),初始化时对于一个点假如再 ...
- windows下命令行复制
在CMD命令提示符窗口中点击鼠标右键,选择“标记”选项,然后按住鼠标左键不动,拖动鼠标标记想要复制的内容.标记完成以后请按键盘上的“回车”键
- keepalived的功能及DR模式搭建笔记
一.HA集群中的相关术语 1.节点(node) 运行HA进程的一个独立主机,称为节点,节点是HA的核心组成部分,每个节点上运行着操作系统和高可用软件服务,在高可用集群中,节点有主次之分,分别称之为主节 ...
- How to enable wire logging for a java HttpURLConnection traffic?
https://stackoverflow.com/questions/1445919/how-to-enable-wire-logging-for-a-java-httpurlconnection- ...
- js 判断是否滚动到底部
$(window).scroll(function(){ var scrollTop = $(this).scrollTop(); //scrollTop() 方法返回或设置匹配元素的滚动条的垂直位置 ...