题目链接

\(|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. LeetCode高频题目(100)汇总-Java实现

    LeetCode高频题目(100)汇总-Java实现       LeetCode高频题目(100)汇总-Java实现 目录 第01-50题 [Leetcode-easy-1] Two Sum [Le ...

  2. nginx 负载均衡 反向代理

    nginx 通过方向代理实现负载均衡,负载均衡是大流量网站要做的措施,单从字面上的意思来理解为N台服务器平均分担负载,不会因为某一台服务器负载高宕机而影响用户访问网站,负载均衡至少需要三台服务器, 既 ...

  3. mysql 查询当月天数

    SELECT day(LAST_DAY('2018-02-01')) 思路: 先通过LAST_DAY() 查找当月最后一天,然后通过day()返回天数.

  4. 序列化---fastjson使用

    该文章主要介绍com.alibaba.fastjson的使用. 首先创建maven工程,导入fastjson.挑个热度高的版本就好了. 首先考虑下,我们通常什么时候会使用序列化和反序列化: 1.将ja ...

  5. Python 3基础教程18-获取用户键盘输入

    有时候,我们需要获取用户的键盘输入的信息,然后得到信息,拿去做一些事情. 请看下面的demo.py # 练习如何通过键盘获取用户输入 x = input('What is your name?') p ...

  6. PostgreSQL 建库建表脚本

    1.创建角色(create_role.sql) drop role if exists "kq_acs";create role "kq_acs" login ...

  7. C#的internal访问修饰符

    文章:C# 访问修饰符internal的访问范围误区释疑 internal访问修饰符限定的类,只能在本程序集中访问.

  8. css3的counter的用法

    很早之前,计数器仅存在于ul,ol等元素中,如何想给其他元素增加计数,就只能通过list-style-image,或者background-image来实现.不过现在css3增加了counter属性, ...

  9. java高精度类尝试

    java高精度尝试, poj2109,比较坑的题目 import java.io.*; import java.util.*; import java.math.*; public class Mai ...

  10. AtCoder Grand Contest 025 Problem D - Choosing Points

    题目大意:输入$n,d1,d2$,你要找到$n^2$个整点 x, y 满足$0 \leqslant x, y<2n$.并且找到的任意两个点距离,既不是$\sqrt{d1}$,也不是 $\sqrt ...