题目链接

\(|S|<=10^5\),时间还是很宽松的。

允许我们使用线性/\(N\log N\)/甚至\(N \sqrt N\)的算法。

设\(l[i]\)表示以\(a[i]\)结尾的最长回文串,\(r[i]\)表示以\(a[i]\)开头的最长的回文串,

那么答案很显然就是\(\max_{i=1}^{len-1}l[i]+r[i+1]\)

怎么求?

回顾一下我们的马拉车算法

for(int i = 1; i < len; ++i){
if(i < maxright)
hw[i] = min(hw[(mid << 1) - i], hw[mid] + mid - i); //min左边的参数是这个点的对称点的hw值,右边的是保证这个部分在这个大回文串之内
else hw[i] = 1;
while(a[i + hw[i]] == a[i - hw[i]]) ++hw[i]; //拓展
if(hw[i] + i > maxright){ //更新右端点
maxright = hw[i] + i;
mid = i;
}
}

我们在每个\(i\)处理出\(hw[i]\)后更新\(i\)~\(i+hw[i]-1\)的\(l\)值,每个位置只需要更新一次就好了,因为我们是从左到右遍历的,因此第一次更新的一定是最优值。所以我们只需要定义一个变量\(p\),表示已经更新到哪里了,然后每次\(for(p->i+hw[i]-1)\),更新\(l\)值,如果\(p\)已经超过\(i+hw[i]-1\),是不会更新的,保证每个位置只被更新一次,也就是保证了时间复杂度是线性的。\(r\)也同理,反过来跑一遍就好了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100010;
char b[MAXN], a[MAXN << 1];
int hw[MAXN << 1], l[MAXN], r[MAXN], ans, n, p = 1;
int main(){
scanf("%s", b);
a[0] = a[1] = '#';
int len = strlen(b);
for(int i = 0; i < len; ++i)
a[(i << 1) + 2] = b[i], a[(i << 1) + 3] = '#';
int maxright = 0, mid; len = (len << 1) + 3;
for(int i = 1; i < len; ++i){
if(i < maxright)
hw[i] = min(hw[(mid << 1) - i], hw[mid] + mid - i);
else hw[i] = 1;
while(a[i + hw[i]] == a[i - hw[i]]) ++hw[i];
if(hw[i] + i > maxright){
maxright = hw[i] + i;
mid = i;
}
for(; p < i + hw[i]; ++p) l[p] = (p - i) + 1 - (a[p] == '#');
}p = len - 1;
for(int i = len - 1; i; --i)
for(; p > i - hw[i]; --p)
r[p] = (i - p) + 1 - (a[p] == '#');
for(int i = 1; i < len - 1; ++i)
ans = max(ans, l[i] + r[i + 1]);
printf("%d\n", ans);
return 0;
}

【洛谷 P4555】 [国家集训队]最长双回文串 (Manacher)的更多相关文章

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

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

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

    P4555 [国家集训队]最长双回文串 题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为\(n\)的串 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. XStream轻松转换xml和java对象

    首先引入所需的jar: xstream-1.4.9.xpp3_min-1.1.4c.dom4j-1.6.1, 或用maven管理jar包时在pom.xml中添加: <!-- https://mv ...

  2. Linux系统安装jdk后出现无法执行binary 文件的错误解决

    这是由于jdk版本的问题,针对Linux系统,Oracle提供了 ARM 的32jdk和64位jdk , 但是也提供了类似这样jdk-8u191-linux-i586.tar.gz32或64位的jdk ...

  3. 如何在指定文件夹下进入jupyter notebook

    第一步: 打开 Anaconda Prompt 第二步: 查看文件夹所在路径 例如:你有个jupyterwork文件夹在 D:\ 路径下 第三步: 在Anaconda Prompt依次输入一下命令: ...

  4. LeetCode 82 ——删除排序链表中的重复元素 II

    1. 题目 2. 解答 新建一个链表,并添加一个哨兵结点,从前向后开始遍历链表. 如果下一个结点的值和当前结点的值相等,则循环向后遍历直到找到一个和当前结点值不相等的结点: 反之,如果下一个结点的值和 ...

  5. redis-Windows下安装与操作

    Redis windows下安装 1.安装 (1)windows把redisbin_x32安装包放在电脑任意的盘里 (2)通过cmd找到对应目录:  D\redisbin_x32 (3)开始安装 D\ ...

  6. NO10——各种欧几里得

    int gcd(int n,int m)//n>m { //最大公约数 int r; while(m) { r = n%m; n = m; m = r; } return n; } int kg ...

  7. android-ViewList的通用ViewHold

    在写ViewList的时候要写Adapter的时候,经常大量的代码都是差不多的. 1 ViewHold 2 if(convertView ==null ){}else{} 3 setTag 4 FIn ...

  8. Linux nohup 后台运行命令

    有一些爬虫的程序需要在后台运行,所以简单总结了一下nohup 的一些用法 基本命令:nohup command  $; 运行之后出现nohup: ignoring input and appendin ...

  9. PhoneGap & HTML5 学习资料网址

    PhoneGap 与 Application Cache应用缓存  http://www.html5cn.org/forum.php?mod=viewthread&tid=40272 加速We ...

  10. 基于bootstrap动态分页

    bootstrap本身的分页有分页组件 但是却是静态的,无法满足要求,分页必须根据当前的总页数来展示 使用插件bootstrap-paginator github下载地址 https://github ...