P4555 [国家集训队]最长双回文串

题目描述

顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同)。

输入长度为\(n\)的串\(S\),求\(S\)的最长双回文子串\(T\),即可将\(T\)分为两部分\(X\),\(Y\),(\(|X|,|Y|≥1\))且\(X\)和\(Y\)都是回文串。

输入输出格式

输入格式:

一行由小写英文字母组成的字符串\(S\)。

输出格式:

一行一个整数,表示最长双回文子串的长度。

说明

对于\(100\%\)的数据,\(2≤|S|≤10^5\)


按套路先把每个位置为中心的回文串长度用\(manacher\)求出来。

然后比较暴力的想法是直接线段树做一下,虽然也可以通过不过不优雅。

预处理出每个点为开头或结尾的最长回文串长度,然后枚举断点就可以了。

如何预处理?发现可以先通过中心的最长回文串预处理一部分,然后扫描一遍,更新非最长的长度。

具体的说,比如\(pre_i\)代表\(i\)开头的最长回文串,那么显然是有\(pre_i=max(pre_{i-2}-2,pre_i)\)的(这里已经插入了'#')

这个技巧用的比较多了,要注意使用。


Code:

#include <cstdio>
#include <cstring>
const int N=2e5+10;
int a[N],t[N],L[N],R[N],n,ans,r;
char s[N],c[N];
int min(int x,int y){return x<y?x:y;}
int max(int x,int y){return x>y?x:y;}
int main()
{
memset(t,0x3f,sizeof(t));
scanf("%s",c+1);
n=strlen(c+1);
s[0]=s[1]='$';
for(int i=1;i<=n;i++) s[i*2]=c[i],s[i*2+1]='$';
n=(n<<1)+1;
for(int rig=0,mid,i=1;i<=n;i++)
{
a[i]=i>rig?1:min(rig-i,a[(mid<<1)-i]);
while(s[i-a[i]]==s[i+a[i]]) ++a[i];
--a[i];
if(a[i]+i>rig) rig=a[i]+i,mid=i;
L[i-a[i]]=max(L[i-a[i]],a[i]);
R[i+a[i]]=max(R[i+a[i]],a[i]);
}
for(int i=3;i<=n;i+=2) L[i]=max(L[i],L[i-2]-2);
for(int i=n;i>0;i-=2) R[i]=max(R[i],R[i+2]-2);
for(int i=1;i<=n;i+=2) ans=max(ans,L[i]+R[i]);
printf("%d\n",ans);
return 0;
}

2018.10.31

洛谷 P4555 [国家集训队]最长双回文串 解题报告的更多相关文章

  1. 洛谷 P4555 [国家集训队]最长双回文串(Manacher)

    题目链接:https://www.luogu.com.cn/problem/P4555 首先明白两个回文串,那么要使两个回文串成立,那么我们只能把$'#'$作为中间节点. 然后我们跑一边Manache ...

  2. 洛谷 P4555 [国家集训队]最长双回文串

    链接: P4555 题意: 在字符串 \(S\) 中找出两个相邻非空回文串,并使它们长度之和最大. 分析: 直接使用马拉车算法求出每个点扩展的回文串.如果枚举两个回文串显然会超时,我们考虑切割一个长串 ...

  3. 洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)

    题意 题目链接 Sol 我的做法比较naive..首先manacher预处理出以每个位置为中心的回文串的长度.然后枚举一个中间位置,现在要考虑的就是能覆盖到i - 1的回文串中 中心最靠左的,和能覆盖 ...

  4. 【洛谷】P4555 [国家集训队]最长双回文串

    P4555 [国家集训队]最长双回文串 题源:https://www.luogu.com.cn/problem/P4555 原理:Manacher 还真比KMP好理解 解决最长回文串问题 转化为长度为 ...

  5. P4555 [国家集训队]最长双回文串

    P4555 [国家集训队]最长双回文串 manacher 用manacher在处理时顺便把以某点开头/结尾的最长回文串的长度也处理掉. 然后枚举. #include<iostream> # ...

  6. Manacher || P4555 [国家集训队]最长双回文串 || BZOJ 2565: 最长双回文串

    题面:P4555 [国家集训队]最长双回文串 题解:就.就考察马拉车的理解 在原始马拉车的基础上多维护个P[i].Q[i]数组,分别表示以i结尾最长回文子串的长度和以i开头的最长回文子串的长度 然后就 ...

  7. P4555 [国家集训队]最长双回文串(回文树)

    题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...

  8. BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)

    BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...

  9. [国家集训队]最长双回文串 manacher

    ---题面--- 题解: 首先有一个直观的想法,如果我们可以求出对于位置i的最长后缀回文串和最长前缀回文串,那么我们枚举分界点然后合并前缀和后缀不就可以得到答案了么? 所以我们的目标就是求出这两个数列 ...

随机推荐

  1. docker in docker

    docker run --rm可以从一个镜像启动容器,并在容器执行完成后自动删除,这在计算任务中非常有用. 例如,我们通过以下步骤完成计算任务容器的启动: 1 将输入数据通过卷挂载方式连接到计算任务容 ...

  2. 请求头(request)和响应头(response)

    说一说常见的请求头和相应头都有什么呢? 1)请求(客户端->服务端[request]) GET(请求的方式) /newcoder/hello.html(请求的目标资源) HTTP/1.1(请求采 ...

  3. http知识点 前端

    前端必须明白的http知识点 对于http的报文格式就不多细说了,做为前端开发,我们需要知道前后端联调时的请求和响应之间请求头和返回头之间的关系和每个字段中的涵意,静态文件资源在加载时我们所观察到可性 ...

  4. 第五模块:WEB开发基础 第1章·HTML&CSS基础

    01-前端介绍 02-HTML介绍 03-HTML文档结构 04-head标签相关内容 05-常用标签一之h1~h6,p,a 06-常用标签一之ul.ol.div.img.span 07-常用标签二- ...

  5. python终极篇 ---django 模板系统

                                                模板系统                                                . MV ...

  6. js如何判断客户端是iOS还是Android等移动终端

    判断原理:JavaScript是前端开发的主要语言,我们可以通过编写JavaScript程序来判断浏览器的类型及版本.JavaScript判断浏览器类型一般有两种办法,一种是根据各种浏览器独有的属性来 ...

  7. lr 常用操作

    lr脚本编写语法: web_add_cookie();:服务器注入cookies lr_save_string("网址或其他","参数2");:一个保存函数,它 ...

  8. LeetCode 169. Majority Element - majority vote algorithm (Java)

    1. 题目描述Description Link: https://leetcode.com/problems/majority-element/description/ Given an array ...

  9. 如何在etherscan提交代币官方信息

    https://ethlinkersupport.zendesk.com/hc/zh-cn/articles/360001334992-%E5%A6%82%E4%BD%95%E5%9C%A8ether ...

  10. 自测之Lesson8:进程操作

    题目:请解释wait是如何同步父子进程的. 程序代码: #include <stdio.h> #include <unistd.h> #include <sys/type ...