【题解】Casting Spells LA 4975 UVa 1470 双倍回文 SDOI 2011 BZOJ 2342 Manacher
首先要吐槽LRJ,书上给的算法标签是“有难度,需要结合其他数据结构”,学完Manacher才发现几乎一裸题
题目的意思是问原串中有多少个wwRwwR这样的子串,其中wR表示w的反串
比较容易看出来,wwRwwR本身是一个回文串,wwR也是一个回文串
最裸的暴力是,我们枚举每一个回文串,然后判断这个回文串的左半边是不是也是个回文串
然后我们考虑用Manacher
我们考虑Manacher的工作原理,是在充分利用原先的信息的前提下,不重复,不遗漏的枚举每个回文串
也就是说,在Manacher的运算过程当中,每个回文串我们都会考虑到
也就是说,我们可以在Manacher的运作过程当中,顺便完成答案的计算,具体操作见下
我们可以画出来这样一张图
# a # b # b # a # a # b # b # a #
0 1 2 3 4 5 6 7 8
我们要更新答案的时候,处在最中间的8号位置,不失一般性,我们处在 i 号位置,要求这个位置是字符#,这个要求的原因很显然
当 i 号位置的回文半径到达4的倍数的时候,说明我们左半边的串的长度是偶数,设当前的回文半径为 r
这时候左半边的串的中心位置就是 i - r/2 ,可以自己手算一下
如果 i - r/2 处的回文半径大于等于 i - r/2 的话,那么显然左半边是回文串,我们找到了一个满足要求子串,就可以ans = max( ans, r )
代码如下:
#include <cstring>
#include <cstdio>
#include <algorithm> using namespace std;
const int MAXN = ; int n;
char str[MAXN], s[MAXN<<]; void input() {
scanf( "%s", str ), n = strlen(str);
int p = ;
for( int i = ; i < n; ++i )
s[p++] = '#', s[p++] = str[i];
s[p++] = '#';
} int rd[MAXN<<]; // 回文半径
void manacher() {
int mx = , p = , len = *n+, ans = ;
for( int i = ; i < len; ++i ) {
if( i < mx ) rd[i] = min( rd[*p-i], mx-i );
else rd[i] = ;
while( i+rd[i] < len && i-rd[i] >= && s[i+rd[i]] == s[i-rd[i]] ) {
if( s[i] == '#' && rd[i] % == && rd[i-rd[i]/] >= rd[i]/ )
ans = max( ans, rd[i] );
++rd[i];
}
if( i+rd[i] > mx ) mx = i+rd[i], p = i;
}
printf( "%d\n", ans );
} int main() {
int T; scanf( "%d", &T );
while( T-- ) input(), manacher();
return ;
}
【题解】Casting Spells LA 4975 UVa 1470 双倍回文 SDOI 2011 BZOJ 2342 Manacher的更多相关文章
- 洛谷 P4287 [SHOI2011]双倍回文题解
前言 用了一种很奇怪的方法来解,即二分判断回文,再进行某些奇怪的优化.因为这个方法很奇怪,所以希望如果有问题能够 hack 一下. 题解 我们发现,这题中要求的是字符串 \(SS'SS'\),其中 \ ...
- BZOJ2342: [Shoi2011]双倍回文
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 923 Solved: 317[Submit][Status ...
- 【BZOJ2342】双倍回文(回文树)
[BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- BZOJ 2342: 【SHOI2011】 双倍回文
题目链接:双倍回文 回文自动机第二题.构出回文自动机,那么一个回文串是一个“双倍回文”,当且仅当代表这个串的节点\(u\)顺着\(fail\)指针往上跳,可以找到一个节点\(x\)满足\(2len_x ...
- [SHOI2011]双倍回文 manacher
题面: 洛谷:[SHOI2011]双倍回文‘ 题解: 首先有一个性质,本质不同的回文串最多O(n)个. 所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间 ...
- BZOJ 2342 [Shoi2011]双倍回文(manacher+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2342 [题目大意] 记Wr为W串的倒置,求最长的形如WWrWWr的串的长度. [题解] ...
- 「BZOJ 2342」「SHOI 2011」双倍回文「Manacher」
题意 记\(s_R\)为\(s\)翻转后的串,求一个串最长的形如\(ss_Rss_R\)的子串长度 题解 这有一个复杂度明显\(O(n)\)的做法,思路来自网上某篇博客 一个双倍回文串肯定当且仅当本身 ...
- BZOJ2342:[SHOI2011]双倍回文
浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://www.lydsy.com/JudgeOnline ...
随机推荐
- JAVA基础学习之路(三)类定义及构造方法
类的定义及使用 一,类的定义 class Book {//定义一个类 int price;//定义一个属性 int num; public static int getMonney(int price ...
- 哈希表 -数据结构(C语言实现)
读数据结构与算法分析 哈希表 一种用于以常数平均时间执行插入.删除和查找操作的数据结构. 但是是无序的 一般想法 通常为一个包含关键字的具有固定大小的数组 每个关键字通过散列函数映射到数组中 冲突:两 ...
- 《Effective C++》读书笔记 条款03 尽可能使用const 使代码更加健壮
如果你对const足够了解,只需记住以下结论即可: 将某些东西声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用于内的对象.函数参数.函数返回类型.成员函数本体. 编译器强制实施 ...
- NodeJs学习笔记01-你好Node
如果你对NodeJs略知一二,不禁会感叹,使用JS的语法和代码习惯就能开发一个网站的后台,实现复杂的数据交互,牛! 对于学习java和php就夹生的小码农来说,简直就是靡靡之音呐~~~ 今晚带着忐忑的 ...
- Office 365 E3功能
本文简要总结了Office 365E3的功能
- nodejs反向代理插件anyproxy安装
目前我使用的是Anyproxy,AnyProxy .这个软件的特点是可以获取到https链接的内容.在2016年年初的时候微信公众号和微信文章开始使用https链接.并且Anyproxy可以通过修改r ...
- 十一:Centralized Cache Management in HDFS 集中缓存管理
集中的HDFS缓存管理,该机制可以让用户缓存特定的hdfs路径,这些块缓存在堆外内存中.namenode指导datanode完成这个工作. Centralized cache management i ...
- 硬件原理图Checklist检查表(通用版)
类别 描述 检视规则 原理图需要进行检视,提交集体检视是需要完成自检,确保没有低级问题. 检视规则 原理图要和公司团队和可以邀请的专家一起进行检视. 检视规则 第一次原理图发出进行集体检视后所有的修改 ...
- C语言实验——时间间隔
Description 从键盘输入两个时间点(24小时制),输出两个时间点之间的时间间隔,时间间隔用“小时:分钟:秒”表示. 如:3点5分25秒应表示为--03:05:25.假设两个时间在同一天内,时 ...
- C语言 指针数组 多维数组
. 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21402047 . 1. 地址算数运算示例 指针算数运算 ...