P4555 最长双回文串
题目描述
顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同)。
输入长度为 n的串 S ,求 S的最长双回文子串 T ,即可将 T 分为两部分 X, Y,( ∣X∣,∣Y∣≥1|X|,|Y|≥1∣X∣,∣Y∣≥1 )且 X 和 Y 都是回文串。
输入输出格式
输入格式:
一行由小写英文字母组成的字符串 S 。
输出格式:
一行一个整数,表示最长双回文子串的长度。
输入输出样例
baacaabbacabb
12
说明
【样例说明】
从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。
对于100%的数据, 2≤∣S∣≤105
Solution:
本题$zyys$啊!~
很容易想到$manacher$,于是先打个板子看看,处理出以$i$为中心的最长回文半径$p[i]$后,就断思路了。
我首先想到的是,在每次更新$p[i]$后,分别处理出以$i$为中心的半径$p[i]$内,每个位置为开头和结尾的最长回文子串长度($manacher$结束后直接枚举断点就可以得到答案),但是这样强行又将复杂度拉到了$O(n^2)$。于是,开始断线~
后面看看巨佬们的思路,豁然**,我是真的蠢啊~
其实,将我开始的思路修改一下即可:
我们维护最长回文半径$p[i]$的同时,再分别维护两个东西,以$i$为结尾的最长回文子串的长度$ll[i]$,和以$i$为开头的最长回文子串的长度$rr[i]$。
那么很显然,因为以$i$为中心的最长回文子串长度为$p[i]-1$,所以每次更新$p[i]$后,我们只需处理出当前这个回文子串的左右边界(中间的每个点的$ll[i],rr[i]$可以在$manacher$结束后$O(n)$处理出),则$ll[i+p[i]-1]=max(ll[i+p[i]-1],p[i]-1)$(更新以$i+p[i]-1$为结尾的最长回文长度),同理$rr[i-p[i]+1]=max(rr[i-p[i]+1],p[i]-1)$。
跑完$manacher$后,我们$O(n)$递推出每个$#$为断点的$ll[i]$和$rr[i]$,其中$rr[i]$因为是$i$结尾的回文长度,所以直接顺推,每往后移一位,最长回文子串长度$-2$,于是$rr[i]=max(rr[i],rr[i-2]-2)$($i-2$是上一个$#$位置),同理$ll[i]$直接逆推,类似地$ll[i]=max(ll[i],ll[i+2]-2)$。
最后枚举每个$#$为断点,更新$ans$就$OK$了。
代码:
#include<bits/stdc++.h>
#define For(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c))
#define Bor(i,a,b,c) for(int (i)=(b);(i)>=(a);(i)-=(c))
#define Min(a,b) ((a)>(b)?(b):(a))
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int N=;
int p[N],ll[N],ans,rr[N],mx,id,cnt;
char s[N],t[N];
int main(){
scanf("%s",t);
int len=strlen(t);
s[++cnt]='$',s[++cnt]='#';
For(i,,len-,)s[++cnt]=t[i],s[++cnt]='#';
s[++cnt]='\0';
For(i,,cnt,){
if(i<mx)p[i]=Min(p[id*-i],mx-i);
else p[i]=;
while(s[i-p[i]]==s[i+p[i]])p[i]++;
if(mx<i+p[i])id=i,mx=i+p[i];
ll[i+p[i]-]=Max(ll[i+p[i]-],p[i]-);
rr[i-p[i]+]=Max(rr[i-p[i]+],p[i]-);
}
For(i,,cnt,)rr[i]=Max(rr[i],rr[i-]-);
Bor(i,,cnt,)ll[i]=Max(ll[i],ll[i+]-);
For(i,,cnt,)if(rr[i]&&ll[i])ans=Max(ans,ll[i]+rr[i]);
cout<<ans;
return ;
}
P4555 最长双回文串的更多相关文章
- P4555 [国家集训队]最长双回文串
P4555 [国家集训队]最长双回文串 manacher 用manacher在处理时顺便把以某点开头/结尾的最长回文串的长度也处理掉. 然后枚举. #include<iostream> # ...
- 洛谷 P4555 [国家集训队]最长双回文串 解题报告
P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...
- Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串
题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...
- 【洛谷】P4555 [国家集训队]最长双回文串
P4555 [国家集训队]最长双回文串 题源:https://www.luogu.com.cn/problem/P4555 原理:Manacher 还真比KMP好理解 解决最长回文串问题 转化为长度为 ...
- BZOJ 2565: 最长双回文串 [Manacher]
2565: 最长双回文串 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1842 Solved: 935[Submit][Status][Discu ...
- 【BZOJ2565】最长双回文串(回文树)
[BZOJ2565]最长双回文串(回文树) 题面 BZOJ 题解 枚举断点\(i\) 显然的,我们要求的就是以\(i\)结尾的最长回文后缀的长度 再加上以\(i+1\)开头的最长回文前缀的长度 至于最 ...
- BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)
BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...
- Tsinsen 最长双回文串
求最长双回文串,正反建回文树求最大. 题目链接:http://www.tsinsen.com/ViewGProblem.page?gpid=A1280 By:大奕哥 #include<bits/ ...
- bzoj 2565: 最长双回文串 manacher算法
2565: 最长双回文串 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...
随机推荐
- 初学Python遇到的坑
问题一 脚本内容 MacBookPro:Desktop mac$ cat wike.py #!/usr/bin/python from urllib.request import urlopen fr ...
- 1.VS Code 开发C#入门 安装Dotnet core
1. dot.net 网站 下载 .NET Core 1.0 (https://www.microsoft.com/net/download/core) 2. 打开命名提示符: 3.dotnet ...
- yield 生成器的运行机制
yield 生成器的运行机制 当你问生成器要一个数时,生成器会执行,直至出现 yield 语句,生成器把 yield 的参数给你,之后生成器就不会往下继续运行. 当你问他要下一个数时,他会从上次的状态 ...
- 剑指Offer的学习笔记(C#篇)-- 和为S的连续正数序列
题目描述 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久,他 ...
- Java代码工具箱之解析单行单列简单Excel
1. 使用开源工具 jxl.jar 2. 功能:解析常规Excel.xls格式测试可行,xlsx未测试.Excel测试格式为常规类似table这种简单布局文件.第一行为标题,后面行为内容.代码 可正确 ...
- vue实现tab切换功能精简版
<template> <div> <p class="tabs" v-for="(list,index) in lists" :c ...
- 如何修改魔兽争霸war3分辨率
如何修改魔兽争霸war3 分辨率 有时候发现老电脑从XP系统升级到WIN7之后,发现玩魔兽不能全屏了(2边会有一些黑屏的).最后检查发现是魔兽在安装注册表之后显示的分辨率跟电脑的实际分辨率不同导致的. ...
- git bush的一些基础命令
git bush的一些基础命令(不区分大小写) 通过命令创建本地仓库 首先自己需要手动建一个文件夹用于本地仓库 进行如下输入,使用cd跳转到刚刚创建的文件夹中 之后再输入 git init 即可创建 ...
- 判断浏览器环境(QQ,微信,安卓设备,IOS设备,PC微信环境,移动设备)
判断浏览器环境(QQ,微信,安卓设备,IOS设备,PC微信环境,移动设备) // ===== 判断浏览器环境 ===== // // 判断是否是QQ环境 function isQQ() { retur ...
- Python循环的一些基本练习
#1:# name = input('请输入你的身份')# if name == 'egon':# print('--> 超级管理员')# elif name == 'tom':# print( ...