Manacher算法求回文半径
这篇讲的比较好,准备一个模板,做题的时候用。
void manacher()
{
int mx = , id = ;
for (int i = ; i <= n; i++)
{
if (mx > i)
p[i] = min(p[id * - i], mx - i);
else
p[i] = ;
while (a[i + p[i]] == a[i - p[i]])
p[i]++;
if (mx < p[i] + i)
{
mx = p[i] + i;
id = i;
}
}
}
这个初始化的时候是从1开始的
for (int i = ; i <= n; i++)
{
a[i * - ] = str[i];
a[i * ] = -;
}
其中p表示回文半径,str是原串,a表示添加字符之后的串
两个例题:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm> using namespace std;
typedef long long LL;
const int maxn = ;
char str[maxn], a[maxn<<];
int p[maxn<<], L[maxn<<], R[maxn<<];
int n;
void manacher()
{
int mx = , id = ;
for (int i = ; i <= n; i++)
{
if (mx > i)
p[i] = min(p[id * - i], mx - i);
else
p[i] = ;
while (a[i + p[i]] == a[i - p[i]])
p[i]++;
if (mx < p[i] + i)
{
mx = p[i] + i;
id = i;
}
}
}
bool solve()
{
for (int i = ; i <= L[]; i++)
{
for (int j = ; j <= R[]; j++)
{
int l = L[i] + ;
int r = R[j] - ;
if (r - l <= )
continue;
int mid = (l + r) / ;
if (p[mid] >= r - mid + )
return true;
}
}
return false;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%s", str + );
n = strlen(str + );
for (int i = ; i <= n; i++)
{
a[i * - ] = str[i];
a[i * ] = '#';
}
n = n * - ;
a[] = '$';
a[n + ] = '@';
manacher();
memset(L, , sizeof(L));
memset(R, , sizeof(R));
for (int i = ; i <= n; i++)
{
int l = i - p[i] + ;
int r = i + p[i] - ;
if (l == )
L[++L[]] = r;
if (r == n)
R[++R[]] = l;
}
if (solve())
puts("Yes");
else
puts("No");
}
return ;
}
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = ;
int str[maxn], a[maxn<<];
int p[maxn<<];
int n;
void manacher()
{
int mx = , id = ;
for (int i = ; i <= n; i++)
{
if (mx > i)
p[i] = min(p[id * - i], mx - i);
else
p[i] = ;
while (a[i + p[i]] == a[i - p[i]])
p[i]++;
if (mx < p[i] + i)
{
mx = p[i] + i;
id = i;
}
}
}
void print()
{
for (int i = ; i <= n; i++)
printf("%d ", p[i]);
}
int main()
{
int T;
int kase = ;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", &str[i]);
for (int i = ; i <= n; i++)
{
a[i * - ] = str[i];
a[i * ] = -;
}
int m = n;
n = n * - ;
a[] = -;
a[n + ] = -;
manacher();
int ans = ;
for (int i = ; i <= n; i += )
p[i] /= ;
for (int i = ; i <= n; i += )
{
if (p[i] * < ans)
continue;
for (int j = p[i]; j * >= ans; j--)
{
if (p[i + j * ] >= j)
{
ans = max(ans, j * );
break;
}
}
}
printf("Case #%d: %d\n", ++kase, ans);
}
return ;
}
Manacher算法求回文半径的更多相关文章
- HDU 5371(2015多校7)-Hotaru's problem(Manacher算法求回文串)
题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...
- SPOJ STC02 - Antisymmetry(Manacher算法求回文串数)
http://www.spoj.com/problems/STC02/en/ 题意:给出一个长度为n的字符串,问其中有多少个子串s可以使得s = s按位取反+翻转. 例如样例:11001011. 10 ...
- hdu5340—Three Palindromes—(Manacher算法)——回文子串
Three Palindromes Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- 马拉车算法——求回文子串个数zoj4110
zoj的测评姬好能卡时间.. 求回文子串的个数:只要把p[i]/2就行了: 如果s_new[i]是‘#’,算的是没有中心的偶回文串 反之是奇回文串 /* 给定两个字符串s,t 结论:s,t不相同的第一 ...
- Codeforces Global Round 7 D2. Prefix-Suffix Palindrome (Hard version)(Manacher算法+输出回文字符串)
This is the hard version of the problem. The difference is the constraint on the sum of lengths of s ...
- Manacher算法求解回文字符串
Manacher算法可以在\(O(N)\)时间内求解出一个字符串的所有回文子串(正反遍历相同的字串). 注:回文串显然有两种,一种是奇数长度,如abczcba,有一个中心字符z:另外一种是偶数个长度, ...
- 马拉车算法——求回文串起点hdu3294
#include<bits/stdc++.h> using namespace std; #define maxn 500005 int p[maxn]; ]; int start; in ...
- Manacher算法 - 求最长回文串的利器
求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
随机推荐
- IE 6最小最大宽度与高度的写法
最小最大宽度,最小最大高度,这是CSS很常见的一个要求.在现代浏览器中,一个 min-height,min-width 就可以解决问题,但是在IE系列,比如IE6则比较繁琐一点.下面总结一些IE 6下 ...
- DEDECMS 关键字不能小于2个字节!
今天在做DEDECMS模板时,突然遇到了“关键字不能小于2个字节!”晕,是怎么回事呢?百度了一下,找到了答案,把他记录下来,方便自己日后再遇到这种问题时,可以查询: <form name=&qu ...
- 简述一个javascript简单继承工具的实现原理
背景 由于本人非常希望能够开发自己的游戏,所以业余时间一直在想着能不能自己一些好玩又有趣的东西出来,最近随着steam上众多独立游戏的爆发,感觉自己又燃烧了起来,所以又拾起了很久以前的一个2d引擎,决 ...
- C++实现base64编码(1)
下面的代码是php里面的base64编码逻辑,确实比我之前的要美观很多,我只是简单的用C++的类进行了一下封装,删除了一些没用的逻辑,基本上还是原来PHP的代码: #include <iostr ...
- hdfs 常用命令
(2)bin/hdfs dfs -mkdir -p /home/雨渐渐 (3)scp /media/root/DCE28B65E28B432E/download/第2周/ChinaHadoop第二讲\ ...
- Gray码 (格雷码) 【二进制】
以下内容是看了Matrix67的关于二进制的blog(Link)的一点总结与摘录. Gray码,中文“格雷码”,是一种特殊的编码,相邻两个格雷码的二进制表示中有且仅有一位不同,且 n 阶 Gray 码 ...
- Deferred
http://blog.allenm.me/2012/01/jquery_deferred_promise_method/ http://www.ruanyifeng.com/blog/2011/08 ...
- java学习之面向对象概念
思考的两种方式: 举例: 把大象放到冰箱里 一.面向过程 :[打开冰箱->把大象放里面->关上冰箱门]面向过程注重的是过程,也就是(动作[函数]),然后按照动作依次去执行就好了. 代表语言 ...
- Linux下高并发网络编程
Linux下高并发网络编程 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时, 最高的并发数量都要受到系统对用户单一进程同时可打 ...
- [LeetCode#154]Find Minimum in Rotated Sorted Array II
The question: Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are ...