[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 ...
随机推荐
- 【笔记】Oracle 窗口函数
Oracle 窗口函数 简单来说,窗口函数是分析函数的一种,通常可以理解成over()函数 构成:函数名①() over(partition by 分组的列名 order by 排序的列名 XXX) ...
- -source 1.5 中不支持 diamond 运算符(中文版idea)
-source 1.5 中不支持 diamond 运算符(中文版idea) 将idea中的各个部分的jdk设为8即可,中文版的如下 1.文件-设置 2.项目上右击-打开模块设置 模块中每一个都要确认是 ...
- 如何使用Delta Lake构建批流一体数据仓库
简介:Delta Lake是一个开源存储层,它为数据湖带来了可靠性.Delta Lake提供了ACID事务.可扩展的元数据处理,并统一了流式处理和批处理数据处理.Delta-Lake运行在现有数据湖 ...
- [GPT] vue 的 quasar 框架 在 layout 模版中 如何获取 子页面当前使用的 useMeta
在 Quasar 框架中,用 Vue Router 的 meta 字段来获取子页面当前使用的 useMeta . 首先,您需要在路由配置中设置子页面的 meta 字段.例如: const rout ...
- WPF 对接 Vortice 调用 D2D 使用 IWICBitmap 离屏渲染
通过 Vortice 库可以使用非常底层的方式调用到 Direct2D1 进行渲染,本文将使用 D2D 离屏渲染到 IWICBitmap 上,再使用一点点反射黑科技,直接将此 IWICBitmap 对 ...
- dotnet 6 创建进程 Process.Start 时设置 UseShellExecute 在 Windows 下对性能的影响
本文将告诉大家,在 dotnet 6 或 dotnet 7 版本里,启动新的进程时,在 StartInfo 设置 UseShellExecute 为 true 和 false 时,对性能的影响 在 d ...
- 为 RabbitMQ 服务器启用 SSL/TLS
为 RabbitMQ 服务器启用 SSL/TLS 目录 为 RabbitMQ 服务器启用 SSL/TLS 为客户端和服务器生成自签名证书 在 RabbitMQ 服务器中启用 TLS/SSL 支持 使用 ...
- Visual Studio 2019 自带混淆工具DotFuscator不需要去网络下载
http://t.zoukankan.com/daizhipeng-p-13492298.html 大家是否还在困扰发布的项目dll容易被人反编译呢,VS2019默认是没有安装DotFuscator的 ...
- 鸿蒙HarmonyOS实战-ArkUI事件(键鼠事件)
前言 键鼠事件是指在计算机操作中,用户通过键盘和鼠标来与计算机进行交互的行为.常见的键鼠事件包括按下键盘上的键.移动鼠标.点击鼠标左键或右键等等.键鼠事件可以触发许多不同的操作,比如在文本编辑器中输入 ...
- Ubuntu20.04桌面版图文安装(超详细)
参考文档: https://baijiahao.baidu.com/s?id=1670100505795119581&wfr=spider&for=pc https://mirrors ...