[SHOI2011]双倍回文 题解
[SHOI2011]双倍回文 题解
看了一些写回文自动机的大佬的代码,我深感敬畏,于是我转身向Manacher走去
现在荣登最优解第一页……

说实话,这个方法的复杂度是很玄学的,但是加了一些优化之后,就几乎不可能被卡到 \(O(n^2)\) 了。
具体思路如下:
预处理字符串部分就略过吧
- 我们预先跑一次 Manacher 算法,考虑到我们其实只需要偶数的回文串的信息,所以将步长设为 2 就行了。
int M(0), R(0), p;
for (int i(1); i < n; i += 2) {
p = R > i ? min(R - i + 1, P[(M<<1) - i]) : 1;
while (s[i + p] == s[i - p]) ++p; // 向两边扩展
if (i + p - 1 > R) M = i, R = i + p - 1; // 更新边界
P[i] = p;
}
接着,我们寻找答案。考虑枚举每一个以
i为中心的偶数回文串。对于这个回文串,我们枚举其回文左区间内的所有点,判断其能否与右区间内对应的区间构成双倍回文即可。换句话来说,假如我们枚举到了j,那么如果j是左侧的合法答案,就一定有j + P[j] > i额,注意一下,这里的
P[i]指的是回文串的直径,是包括了中间点的元素的。也就是说,回文串所在区间其实是(i - P[i], i + P[i])(闭区间!)但是,这并不是充要条件。我们考虑这样一种情况

这个时候,
j其实是不合法的,因为绿色的区间才是合法的区间(合法的区间一定是被i的回文区间完全包含的!)。所以,对于合法区间的中点,一定在i的做右区间中点的左边或者右边。那么实际上,我们只需要枚举(i, i + P[i]/2]作为中点即可。小小的优化:我们需要最大值,所以令答案为
ans,我们枚举(i + ans, i + P[i]/2]即可。而且,我们需要的偶数的回文串,所以步长也可以设为 2 来枚举的。
参考代码:
#include <stdio.h>
#define N 1000006
int n, P[N];
char s[N];
inline int min(int x, int y) {
return x < y ? x : y;
}
inline int max(int x, int y) {
return x > y ? x : y;
}
int main() {
scanf("%d", &n);
char tmp;
do tmp = getchar(); while (tmp < 'a');
s[0] = '^', s[1] = '#', s[2] = tmp, s[3] = '#';
for (int i(2); i <= n; ++i) {
s[(i<<1)] = getchar(), s[(i<<1)|1] = '#';
}
// printf("%s\n", s);
int ans(0);
int M(0), R(0), p;
n = (n<<1) + 2;
for (int i(1); i < n; i += 2) {
p = R > i ? min(R - i + 1, P[(M<<1) - i]) : 1;
while (s[i + p] == s[i - p]) ++p; // 向两边扩展
if (i + p - 1 > R) M = i, R = i + p - 1; // 更新边界
P[i] = p;
}
// 寻找答案
for (int i(1); i < n; i += 2) {
int p = P[i] / 2 + 1;
for (int r(ans); r < p; r += 2) {
if (P[i + r] > r && P[i - r] > r) ans = r;
}
}
printf("%d\n", ans + ans);
return 0;
}
[SHOI2011]双倍回文 题解的更多相关文章
- 洛谷 P4287 [SHOI2011]双倍回文题解
前言 用了一种很奇怪的方法来解,即二分判断回文,再进行某些奇怪的优化.因为这个方法很奇怪,所以希望如果有问题能够 hack 一下. 题解 我们发现,这题中要求的是字符串 \(SS'SS'\),其中 \ ...
- [SHOI2011]双倍回文 manacher
题面: 洛谷:[SHOI2011]双倍回文‘ 题解: 首先有一个性质,本质不同的回文串最多O(n)个. 所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间 ...
- Manacher || BZOJ 2342: [Shoi2011]双倍回文 || Luogu P4287 [SHOI2011]双倍回文
题面:[SHOI2011]双倍回文 题解:具体实现时,就是在更新mr时维护前半段是回文串的最长回文串就好了 正确性的话,因为到i时如果i+RL[i]-1<=mr,那么答案肯定在i之前就维护过了: ...
- BZOJ2342: [Shoi2011]双倍回文
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 923 Solved: 317[Submit][Status ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...
- bzoj 2342: [Shoi2011]双倍回文 -- manacher
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符 ...
- BZOJ2342 Shoi2011 双倍回文 【Manacher】
BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...
- BZOJ 2342 [Shoi2011]双倍回文(manacher+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2342 [题目大意] 记Wr为W串的倒置,求最长的形如WWrWWr的串的长度. [题解] ...
- BZOJ2342:[SHOI2011]双倍回文
浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://www.lydsy.com/JudgeOnline ...
随机推荐
- 快速获取使用dblink的视图的全部字段
快速获取使用dblink的视图的全部字段 默认情况下,使用dblink连接的视图在PL/SQL是没法通过代码助手获取全部的字段的 如果要获取全部字段的话,可以使用一个奇怪的方法 对要获取的使用dbli ...
- 力扣610(MySQL)-判断三角形(简单)
题目: 表: Triangle 写一个SQL查询,每三个线段报告它们是否可以形成一个三角形. 以 任意顺序 返回结果表. 查询结果格式如下所示. 示例1: 解题思路: 判断是否形成三角形的准则是:两 ...
- 开课啦 dubbo-go 微服务升级实战
简介: 杭州开课啦教育科技有限公司是一家致力于为中小学生提供学习辅导的在线教育公司,目前公司后端服务基础设施主要依托于阿里云原生,其中包含计算.网络.存储以及 Kubernetes 服务. 技术选型背 ...
- 一款基于Vue3实现的漂亮且功能强大的在线海报设计器
大家好,我是 Java陈序员. 我们在工作中经常需要设计各种各样的图片,海报.产品图.文章图片.视频/公众号等. 我们可以选择使用 PS 来设计图片,但是有时候想快速完成任务,有没有一款工具支持快速生 ...
- 大模型高效微调详解-从Adpter、PrefixTuning到LoRA
一.背景 目前NLP主流范式是在大量通用数据上进行预训练语言模型训练,然后再针对特定下游任务进行微调,达到领域适应(迁移学习)的目的. 指令微调是预训练语言模型微调的主流范式 其目的是尽量让下游任务的 ...
- ruby和glang的md5和sha1加密对比
ruby和glang的md5和sha1加密对比 package main import ( "crypto/md5" "crypto/sha1" "f ...
- 介绍几种常用的Oracle客户端工具
首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...
- idea修改项目中某个模块名称
1.修改模块名称 2.修改文件夹名称 3.修改本模块里面pom的名称 4.修改其他模块里面引用的名称
- uni-app 安卓和IOS更新方案
一.安卓平台 整包更新(apk),即常规的整个App安装包重新下载安装. 资源热更新(wgt),即App并重新安装,里面的js等前端代码进行更新. Android App,可以直接下载新的apk,只要 ...
- vue3编译优化之“静态提升”
前言 在上一篇 vue3早已具备抛弃虚拟DOM的能力了文章中讲了对于动态节点,vue做的优化是将这些动态节点收集起来,然后当响应式变量修改后进行靶向更新.那么vue对静态节点有没有做什么优化呢?答案是 ...