POJ 3974 Palindrome Manacher算法题解

本题就是求最长的回文子串。

字符串超长,不过限时却是也很长的15秒,最长的限时之一题目了,如果限时短点的话,估计能过的人不多。

使用Mancher算法是可以秒杀的。

模板式的Manacher算法:

#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <limits.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;

const int MAX_N = 1000002;
char s[MAX_N<<1];
int P[MAX_N<<1], len;
inline int MIN(int a, int b) { return a < b? a : b; }
inline int MAX(int a, int b) { return a > b? a : b; }

void preProcess()
{
	int i = len-1, j = len<<1;
	s[j+2] = '\0';
	s[j+1] = '#';
	for (; i >= 0; i--)
	{
		s[j--] = s[i];
		s[j--] = '#';
	}
	s[0] = '~';
}

int Manacher()
{
	len = strlen(s);
	preProcess();
	len = len << 1 | 1;
	int maxLen = 0, right = 0, cen = 0;
	for (int i = 1; i <= len; i++)
	{
		P[i] = i<right? MIN(P[(cen<<1)-i], right-i) : 1;
		while (s[i-P[i]] == s[i+P[i]]) P[i]++;

		maxLen = MAX(maxLen, P[i]);

		if (right < i+P[i]) cen = i, right = i+P[i];
	}
	return maxLen-1;
}

int main()
{
	int t = 1;
	while (gets(s) && strcmp(s, "END") != 0)
	{
		printf("Case %d: %d\n", t++, Manacher());
	}
	return 0;
}

POJ 3974 Palindrome Manacher算法题解

时间: 2024-10-07 14:11:32

POJ 3974 Palindrome Manacher算法题解的相关文章

POJ 3974 Palindrome Manacher

题目大意 给出一个字符串,求出这个字符串的最长回文子串. 思路 前来学习著名的Manacher算法. 这是一个线性时间求出回文子串的算法.具体来说,对于我们弄出的一个回文串,它对于后面的串并不是,没有用的,因为它的左右两侧是相同的,那么自然可以用左边的信息去更新右边. 设p[i]为第i个字符的回文半径,_max为max{p[i]+i},也就是最远可以更新的点.之后枚举的时候,如果当前点的位置小于_max,那么就用之前的信息去更新当前位置.否则p[i]=1.之后暴力向两边匹配.然后它就O(n)啦!

POJ 3259 Wormholes SPFA算法题解

本题其实也可以使用SPFA算法来求解的,不过就一个关键点,就是当某个顶点入列的次数超过所有顶点的总数的时候,就可以判断是有负环出现了. SPFA原来也是可以处理负环的. 不过SPFA这种处理负环的方法自然比一般的Bellman Ford算法要慢点了. #include <stdio.h> #include <string.h> #include <limits.h> const int MAX_N = 501; const int MAX_M = 2501; const

POJ 3461 Oulipo KMP算法题解

本题就是给出很多对字符串,然后问一个字符串在另外一个字符串出现的次数. 就是所谓的Strstr函数啦. Leetcode有这道几乎一模一样的题目. 使用KMP算法加速,算法高手必会的算法了. 另外看见讨论说什么使用KMP还超时,最大可能是没有真正理解next table的含义,写了错误的代码,故此虽然自己运行结果正确,但是却没有真正发挥next table的作用,使得算法退化为暴力法了,所以运行正确,但超时. KMP参考: http://blog.csdn.net/kenden23/articl

POJ 2560 Freckles Prime算法题解

本题是求最小生成树. 给出的是坐标节点,然后需要根据这些坐标计算出各个点之间的距离. 除此就是标准的Prime算法了,能使用Prime的基本上都可以使用Kruskal. 这些经典的算法一定要多写,熟练掌握,否则很难灵活运用的. 而且经典的算法之所以为经典,原因之一是没那么容易自己凭空想象出来的,所以要熟练. #include <stdio.h> #include <string.h> #include <queue> #include <float.h> #

POJ 3974 Palindrome | 马拉车模板

给一个字符串,求最长回文字串有多长 #include<cstdio> #include<algorithm> #include<cstring> #define N 1000005 using namespace std; int n,m,T,p[N*2],ans; char s[2*N],t[N]; void manacher() { int id=0,pos=0,x=0; for (int i=1;i<+n;i++) { if (pos>i) x=min

poj 3974 Palindrome

/* 裸地manachar */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1000010 using namespace std; int l,len[maxn]; char s[maxn],ss[maxn]; int manachar() { int ans=0; int id=-1,mx=-1; for(int i=1;i<=l;i++) { if(id+mx-i&g

后缀数组 POJ 3974 Palindrome &amp;&amp; URAL 1297 Palindrome

题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串中心位置,RMQ询问LCP = min (height[rank[l]+1] to height[rank[r]]),注意的是RMQ传入参数最好是后缀的位置,因为它们在树上的顺序未知,且左边还要+1. #include <cstdio> #include <algorithm> #in

【转载】Manacher算法

本文原创:http://www.cnblogs.com/BigBallon/p/3816890.html只为了记录学习,不为抄袭!http://www.felix021.com/blog/read.php?2040 对于Manacher算法,主要的作用是用来求一个字符串的最长回文子串.这个算法的时间复杂度书线性的,即O(n)下面我分两个部分来讲1)预处理这个算法的精妙之处在于巧妙地避免了考虑回文子串的长度是奇数还是偶数(如果你还不知道什么是回文数,回文串,请自行baidu)在Manacher算法

【POJ 3974】 Palindrome

[POJ 3974] Palindrome Manacher纯模板题 忘记的时候可以拿来找感觉 代码如下: #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; char str[1111111]; char nwstr[2333333]; int p[2333333]; int Manacher() { int len