首先要吐槽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的更多相关文章

  1. 洛谷 P4287 [SHOI2011]双倍回文题解

    前言 用了一种很奇怪的方法来解,即二分判断回文,再进行某些奇怪的优化.因为这个方法很奇怪,所以希望如果有问题能够 hack 一下. 题解 我们发现,这题中要求的是字符串 \(SS'SS'\),其中 \ ...

  2. BZOJ2342: [Shoi2011]双倍回文

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 923  Solved: 317[Submit][Status ...

  3. 【BZOJ2342】双倍回文(回文树)

    [BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...

  4. BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集

    2342: [Shoi2011]双倍回文 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1123  Solved: 408 题目连接 http://w ...

  5. BZOJ 2342: 【SHOI2011】 双倍回文

    题目链接:双倍回文 回文自动机第二题.构出回文自动机,那么一个回文串是一个“双倍回文”,当且仅当代表这个串的节点\(u\)顺着\(fail\)指针往上跳,可以找到一个节点\(x\)满足\(2len_x ...

  6. [SHOI2011]双倍回文 manacher

    题面: 洛谷:[SHOI2011]双倍回文‘ 题解: 首先有一个性质,本质不同的回文串最多O(n)个. 所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间 ...

  7. BZOJ 2342 [Shoi2011]双倍回文(manacher+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2342 [题目大意] 记Wr为W串的倒置,求最长的形如WWrWWr的串的长度. [题解] ...

  8. 「BZOJ 2342」「SHOI 2011」双倍回文「Manacher」

    题意 记\(s_R\)为\(s\)翻转后的串,求一个串最长的形如\(ss_Rss_R\)的子串长度 题解 这有一个复杂度明显\(O(n)\)的做法,思路来自网上某篇博客 一个双倍回文串肯定当且仅当本身 ...

  9. BZOJ2342:[SHOI2011]双倍回文

    浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://www.lydsy.com/JudgeOnline ...

随机推荐

  1. lock+Condition

    关键字 synchronized+wait/notify/notifyAll可以实现等待/通知模式,类ReentrantLock可以实现同样的功能,但需要借助Condition对象.Condition ...

  2. LeetCode - 136. Single Number - ( C++ ) - 解题报告 - 位运算思路 xor

    1.题目大意 Given an array of integers, every element appears twice except for one. Find that single one. ...

  3. Too many open files错误与解决方法

    致前辈:该问题的解决思路给了我很大的启发,文章作者Lis, Linux资深技术专家. 问题现象:这是一个基于Java的web应用系统,在后台添加数据时提示无法添加,于是登陆服务器查看Tomcat 日志 ...

  4. Python中的名字隐藏

    Python对于module文件中的name是没有private和public区分的,严格来说,在module文件重定义的任何name,都可以被外界访问.但是,对于 from module imort ...

  5. C++标准库算法

    一.只读算法 1. find() 2. count() 3. accumulate 4. equal 二.写入算法 1. fill 2. fill_n 3. copy 4. replace 5. re ...

  6. CentOS 6安装thrift支持erlang开发

    早前,在我的博文thrift多平台安装介绍了如何在debian/ubuntu下面安装thrift,并支持erlang开发的.而在CentOS平台下,并没有成功安装.经过不断摸索,终于成功了,这篇博文就 ...

  7. 【转载】Windows下Mysql5.7开启binlog步骤及注意事项

    转自:https://www.cnblogs.com/wangwust/p/6433453.html 1.查看是否开启了binlog:show binary logs; 默认情况下是不开启的. 2.开 ...

  8. 火狐浏览器(FireFox)安装Flash插件失败处理方法

    最近不知道怎么了,总是嫌弃IE,可能是被网络流量监测的网址给搞得了,弄了火狐浏览器,也安装了猎豹,这里不对浏览器做评价 好多朋友安装好火狐(FireFox)的时候发现之前不是有装IE的Flash播放插 ...

  9. 错误 10 非静态的字段、方法或属性“Test10.Program.a”要求对象引用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test ...

  10. java 基础 --多态--009

    1, 多态:同一个对象(事物),在不同时刻体现出来的不同状态 2, 多态的前提: A: 要有继承关系 B: 要有方法的重写 C: 要有父类引用指向子类对象 父 f = new 子(); 3, 多态访问 ...