[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 ...
随机推荐
- Redis基础(一)——字符串、hash类型的基本使用
day09--Redis Redis介绍和安装 # Redis:软件,存储数据的,速度非常快,Redis是一个key-value存储系统(没有表的概念),cs架构的软件 服务端 客户端(python作 ...
- 如何使用XSSFWorkbook读取文本薄?
[版权声明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18146625 出自[进步*于辰的博客] 1.文件兼容类 ...
- vue 弹出框挂载富文本,富文本()无法实例化问题
因为elementUI的dialog组件,他是v-if渲染,再页面刚加载时,这个弹出框还未进行挂载,我们就让他v-show显示. ,富文本实例再mounted里面挂载即可
- maven BUILD FAILURE
maven BUILD FAILURE 使用命令进行导包失败,错误为BUILD FAILURE 然后使用mvn help:system看一下是不是maven有问提 然后出现了新的错误No plugin ...
- 力扣485(java)-最大连续数1的个数(简单)
题目: 给定一个二进制数组, 计算其中最大连续 1 的个数. 示例: 输入:[1,1,0,1,1,1]输出:3解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3. 提示: 输入 ...
- Serverless 场景排查问题利器 : 函数实例命令行操作
简介:实例命令行功能的推出希望能消除用户使用 Serverless 的"最后一公里",直接将真实的函数运行环境展现给用户. 背景介绍 全托管的 Serverless 计算平台能给 ...
- [Trading] 日间交易中的成交量分析 - 使用成交量趋势来提高你的效果
在交易中,成交量代表在特定时期内股票或期货合约的易手单位数量. 交易员将其作为一个关键指标,因为它让他们知道资产的流动性水平,以及他们在接近当前价格的情况下买入或卖出头寸的容易程度,这可能是一个移动的 ...
- dotnet OpenXML 聊聊文本段落对齐方式
本文来和大家聊聊在 OpenXML 里面,文本段落对齐方式.在 Word 和 PPT 的文本段落对齐规则是相同的,对齐的规则比较多,本文将一一告诉大家 文本的段落对齐,需要设置给段落属性上,在 Ope ...
- C++多态与虚拟:C++编译器对函数名的改编(Name Mangling)
如果函数名称都相同(也就是被overloaded),编译器在面对你的函数唤起动作时,究竟是如何确定调用哪个函数实体呢?事实上,编译器把所有同名的overloaded functions视为不同的函数, ...
- FPGA最大工作频率教程
FPGA最大工作频率教程 1. Quartus的时序分析 作为编译过程的一部分,Quartus对布局布线的电路做时序分析.在编译报告里,展开"Timing Analyzer",这 ...