[国家集训队]最长双回文串 manacher
题解:
首先有一个直观的想法,如果我们可以求出对于位置i的最长后缀回文串和最长前缀回文串,那么我们枚举分界点然后合并前缀和后缀不就可以得到答案了么?
所以我们的目标就是求出这两个数列,
我们令f[i] 表示以i为结尾的最长回文后缀的长度,g[i]表示以i为开头的最长回文后缀的长度。
由于要找回文串,因此我们先想到manacher。
然后我们可以发现对于这样一个串:
原串:xxxxxxxxxx
新串:#x#x#x#x#x#x#x#x#x#x#
我们可以观察到,假设这时我们已经求出了f和g,那么对于任意位置而言,合并出的最长双回文串中,都是“偶串”,且有一半是'#',一半是原串。
因此我们可以直接合并f[i-1] 和 g[i],并用ans记录最大值,那么这时真正的答案就是ans / 2.

假设我们manacher已经求到了第i位,此时i的最长回文半径是R,且j已经被包括在R里面了,那么显然i对j的贡献是(j - i) * 2 + 1。
而因为贡献只和i与j的位置有关,并且我们的i是从1开始,逐渐递增的,因此对于任意一个j,第一次将它更新的i必然可以产生最优解,因此每个j会且仅会被更新一次。
而被更新的j显然也是递增的,因为如果j后面的k已经被更新的话,说明之前已经有一个i可以使得k被覆盖在内了。那么j既然在k前面,肯定也被覆盖过了,
因此求出f[j]时,j肯定是递增的(也就是说肯定是先求出前面的在求出后面的),因此我们可以直接维护一个指针t(这个指针只是字面上的指针),表示当前已经更新到了t,
一旦被覆盖的MaxRight > t,我们就直接用当前的i来更新t。
对于前缀回文串,我们直接把字符串翻转过来,然后再做一遍相同的操作,再把得到的数组反转回来就可以了
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 202000
/*处理出前缀半径和后缀半径,然后合并。可以发现,在扩充了数列之后(#),
获取的最长双回文串一定是偶串,且# 和 真实字符数量相同。
因此ans就是合并后的最长长度/2*/
int n, pos, maxn, ans;
int f[AC], g[AC], tmp[AC], r[AC];
char s[AC], p[AC]; void pre()//读入
{
scanf("%s", s + );
n = strlen(s + );
for(R i = n; i; --i) s[i * ] = s[i];
n = * n + ;
for(R i = ; i <= n; i += ) s[i] = '#';
for(R i = ; i <= n; i++) p[i] = s[n - i + ];//把原串倒过来做一遍就是后缀了
s[] = p[] = '$', s[n + ] = p[n + ] = '$';
} void build()//处理出前缀半径和后缀半径
{
int t = ;
pos = maxn = ;
for(R i = ; i <= n; i++)
{
r[i] = maxn > i ? min(r[ * pos - i], maxn - i + ) : ;
while(s[i - r[i]] == s[i + r[i]]) ++r[i];
if(i + r[i] - > maxn)
{
maxn = i + r[i] - , pos = i;
if(maxn > t)//更新后缀
{
for(R j = t + ; j <= maxn; j++) f[j] = (j - i) * + ;
t = maxn;
}
}
}
pos = maxn = t = ;
for(R i = ; i <= n; i++)
{
r[i] = maxn > i ? min(r[ * pos - i], maxn - i + ) : ;
while(p[i - r[i]] == p[i + r[i]]) ++r[i];
if(i + r[i] - > maxn)
{
maxn = i + r[i] - , pos = i;
if(maxn > t)//更新后缀
{
for(R j = t + ; j <= maxn; j++) tmp[j] = (j - i) * + ;
t = maxn;
}
}
}
for(R i = ; i <= n; i++) g[i] = tmp[n - i + ];
// for(R i = 1; i <= n; i++) printf("%d ", f[i]);
// printf("\n");
} inline void upmax(int &a, int b)
{
if(b > a) a = b;
} void work()//合并
{
for(R i = ; i <= n; i++)
upmax(ans, f[i - ] + g[i]);
printf("%d\n", ans/);
} int main()
{
freopen("in.in", "r", stdin);
pre();
build();
work();
fclose(stdin);
return ;
}
[国家集训队]最长双回文串 manacher的更多相关文章
- BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)
BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...
- luoguP4555 [国家集训队]最长双回文串 manacher算法
不算很难的一道题吧.... 很容易想到枚举断点,之后需要处理出以$i$为开头的最长回文串的长度和以$i$为结尾的最长回文串的长度 分别记为$L[i]$和$R[i]$ 由于求$R[i]$相当于把$L[i ...
- 洛谷P4555 [国家集训队]最长双回文串(manacher 线段树)
题意 题目链接 Sol 我的做法比较naive..首先manacher预处理出以每个位置为中心的回文串的长度.然后枚举一个中间位置,现在要考虑的就是能覆盖到i - 1的回文串中 中心最靠左的,和能覆盖 ...
- 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好理解 解决最长回文串问题 转化为长度为 ...
- Manacher【p4555】 [国家集训队]最长双回文串
题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...
- P4555 [国家集训队]最长双回文串(回文树)
题目描述 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同). 输入长度为 n 的串 S ,求 S 的最长双回文子串 T ,即可 ...
随机推荐
- Typeahead的使用总结
Typeahead是Bootstrap的自动补全JS插件. 最近项目中用到,总结一下. 与autocomplish类似,通过ajax实现,实现流程是前台输入关键字,后台根据关键字查询出信息,构造jso ...
- linux_fdisk命令详解,关于分区的详解
这篇文章写的十分详细,特别的好 fdisk -l 可以列出所有的分区,包括没有挂上的分区和usb设备.我一般用这个来查找需要挂载的分区的位置,比如挂上u盘. 实例解说Linux中fdisk分区使用方法 ...
- Kubernetes网络方案的三大类别和六个场景
欢迎访问网易云社区,了解更多网易技术产品运营经验. 本文章根据网易云资深解决方案架构师 王必成在云原生用户大会上的分享整理. 今天我将分享个人对于网络方案的理解,以及网易云在交付 Kubernetes ...
- vuecli结合eslint静态检查
vuecli结合eslint静态检查 搭建vue项目开发可能选择vue-cli项目脚手架快速创建vue项目.(https://github.com/vuejs/vue-cli) 安装vue-cli n ...
- Linux命令应用大词典-第30章 审计系统
30.1 auditctl:控制内核的审计系统 30.2 aureport:生成审计信息报表 30.3 ausearch:搜索审计记录 30.4 autrace:跟踪指定进程 30.5 audit-v ...
- 基于Python的接口自动化
第一步 Python的安装配置 打开官网: https://www.python.org/downloads/ 目前官网上已经更新到3.6.1啦,有两个版本,大家可以按自己喜欢的去下载,我自己选择的是 ...
- jvm 语法糖
jvm 语法糖主要包括: 1. 泛型 相同擦除类型参数,返回值不同也可以编译成功, 对比方法重载矛盾. 原因:class文件格式中,只要描述符不是完全一致的两个方法就可以共存. 擦 ...
- New Year and Old Property :dfs
题目描述: Limak is a little polar bear. He has recently learnt about the binary system. He noticed that ...
- ElasticSearch 论坛搜索查询语句
概述 研究论坛搜索如何综合时间和TF/IDF权重. 自定义权重计算的效率问题 数据结构 假设有一个论坛的搜索 字段包括: subject:标题 message:内容 dateline:发布时间 tag ...
- Python3 Tkinter-Listbox
1.创建 from tkinter import * root=Tk() lb=Listbox(root) for item in ['python','tkinter','widget']: lb. ...