博客
关于我
【ybt金牌导航2-1-2】【luogu P4287】双倍回文
阅读量:325 次
发布时间:2019-03-04

本文共 1222 字,大约阅读时间需要 4 分钟。

双倍回文

题目链接: /

题目大意

要在字符串里面找一个子串,使得它能被分为完全相同的两半。而且这两半应该是回文串,而且长度是偶数。

找最大的这种子串,输出最大的长度。

思路

首先看到回文串,把马拉车模板搞出来。

然后再看。

其实根据题目,可以看出,这个大的子串也是回文串,而且长度也是偶数。
那为奇数的回文串全部没用,也不能用,就不用算。

那你考虑在跑马拉车的时候就把答案算出来。

那你想,你要看三个回文串,那肯定是在第三个处理,因为这个时候前两个都求出来了。
那要什么条件呢?
首先,它中心要在大回文串的右端点的左边,这样,它才有机会被包含在里面。那你大回文串选什么呢?为了让结果都找到,肯定是要右端点最大的。那就是马拉车里面的 m a x r maxr maxr 了。
那而且,它的左边是要在大回文串中心的左边,这样它才可以覆盖玩大回文串右边的整个区域。

那可以的话,我们就确定了大回文串的右边的范围:从大回文串的中心到它的中心。(它是右边的小回文串)

那就可以算出这个符合的子串的长度。

那你把找到的都去最大值,那就是答案了。

代码

#include
#include
using namespace std;int n, f[1500001], ans;char c[1500001], s[500001];void Manacher() { int maxn = 0, maxr = 0; for (int i = 1; i <= n; i += 2) { //因为规定回文串重心一定是#,另一种就不能用了 if (2 * maxn - i > 0) f[i] = min(f[2 * maxn - i], maxr - i); else f[i] = maxr - i; f[i] = max(1, f[i]); if (i < maxr && i - f[i] < maxn)//看着是否能成为规定的串 ans = max(ans, (i - maxn) * 2); while (i - f[i] >= 1 && i + f[i] <= n && c[i - f[i]] == c[i + f[i]]) f[i]++; if (i + f[i] > maxr) { maxr = i + f[i]; maxn = i; } }}int main() { scanf("%d", &n); scanf("%s", s + 1); c[1] = '#'; for (int i = 1; i <= n; i++) { c[i << 1] = s[i]; c[i << 1 | 1] = '#'; } n = n << 1 | 1; Manacher(); printf("%d", ans); return 0;}

转载地址:http://oavh.baihongyu.com/

你可能感兴趣的文章
【ASP.NET】ASP.NET中权限验证使用OnAuthorization实现
查看>>
第9章 用户自己建立数据类型
查看>>
02、MySQL—数据库基本操作
查看>>
RedHat Linux-配置YUM仓库
查看>>
Redis数据类型
查看>>
1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富
查看>>
1907: 树的路径覆盖
查看>>
OpenJDK1.8.0 源码解析————HashMap的实现(一)
查看>>
MySQL-时区导致的时间前后端不一致
查看>>
2021-04-05阅读小笔记:局部性原理
查看>>
将Java编译为本地代码
查看>>
go语言简单介绍,增强了解
查看>>
2.1 Kubernetes--Pod
查看>>
python file文件操作--内置对象open
查看>>
Error connecting to undo manager of souce file
查看>>
ERP/MIS开发 LLBL Gen多表操作
查看>>
Remove function
查看>>
在没实践机会的前提下,如何跨越级别
查看>>
从面试官角度告诉大家如何准备项目方面的描述
查看>>
去创业公司不能有一夜暴富的侥幸,更不能指望掉馅饼
查看>>