【manacher】HDU3068-最长回文

【题目大意】

给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度。

【manacher知识点】

①mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于 i 和 j 对称,以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有 P[i] = P[j]。

②当 P[j] > mx - i 的时候,以S[j]为中心的回文子串不完全包含于以S[id]为中心的回文子串中,但是基于对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以 S[i]为中心的回文子串,其向右至少会扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,就只能一个一个匹配了。

③对于 mx <= i 的情况,无法对 P[i]做更多的假设,只能P[i] = 1,然后再去匹配了

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 using namespace std;
 7 const int MAXN=110000+50;
 8 char str[MAXN],s[MAXN*2];
 9 int p[MAXN*2];
10
11 void init()
12 {
13     s[0]=‘$‘;s[1]=‘#‘;
14     int j=1;
15     for (int i=0;str[i];i++)
16     {
17         s[++j]=str[i];
18         s[++j]=‘#‘;
19     }
20     //cout<<s<<endl;
21 }
22
23 void solve()
24 {
25     int mx=0,mxid=0;
26     memset(p,0,sizeof(p));
27     for (int i=1;s[i];i++)
28     {
29         if (mx>i) p[i]=(p[2*mxid-i]<(mx-i)?p[2*mxid-i]:(mx-i));
30             else p[i]=1;
31         while(s[i-p[i]]==s[i+p[i]]) p[i]++;
32         if (i+p[i]>mx)
33         {
34             mx=i+p[i];
35             mxid=i;
36         }
37     }
38 }
39
40 int getans()
41 {
42     int len=strlen(str)*2+2;
43     int ans=-1;
44     for (int i=1;i<len;i++) ans=max(ans,p[i]);
45     ans--;
46     return ans;
47 }
48
49 int main()
50 {
51     while (scanf("%s",str)!=EOF)
52     {
53         init();
54         solve();
55         cout<<getans()<<endl;
56     }
57     return 0;
58 }
时间: 2024-12-28 20:24:52

【manacher】HDU3068-最长回文的相关文章

HDU3068 最长回文【manacher算法】

最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 32452 Accepted Submission(s): 11908 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case

hdu3068最长回文(Manacher算法)

简单来说这是个很水的东西.有点dp的思想吧.推荐两个博客,很详细. http://blog.csdn.net/xingyeyongheng/article/details/9310555 http://blog.csdn.net/ggggiqnypgjg/article/details/6645824 然后以为随便学点然后去复习,结果……呵呵.什么鬼数据,两行之间用空行隔开……没看到一直wa半节课…… hdu3068最长回文 var s1,s2:ansistring; s:array[0..10

Manacher求最长回文

#1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?" 小Ho奇怪的问道:"什么叫做最长回文子串呢?" 小Hi回答道:"一个字符串中连续的一

HDU 4513 吉哥系列故事——完美队形II manacher求最长回文

题目来源:吉哥系列故事--完美队形II 题意:中文 思路:在manacher算法向两边扩展的时候加判断 保证非严格递减就行了 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100110; int a[maxn<<1]; int b[maxn<<1]; int dp[maxn<<1]; int

hdu-3068 最长回文 【Manacher算法】

Manacher算法学习资料:http://blog.csdn.net/dyx404514/article/details/42061017 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9282    Accepted Submission(s): 3194 Problem Description 给出一个只由小写英文字符

[hdu3068 最长回文]Manacher算法,O(N)求最长回文子串

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文串并更新答案,复杂度O(N3). 枚举回文串的对称轴i,以及回文半径r,由i和r可确定一个子串,然后暴力判断即可.复杂度O(N2). 在上一步的基础上,改进判断子串是否是回文串的算法.记fi(r)=(bool)以i为对称轴半径为r的子串是回文串,fi(r)的值域为{0, 1},显然fi(r)是关于r

【最长回文子串】HDU3068最长回文【Manacher算法】

一张图领悟Manacher算法,计算字符串最长回文子串 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S 两组case之间由空行隔开(该空行不用处理)

HDU3068 最长回文 MANACHER+回文串

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S两组case之间由空行隔开(该空行不用处理)字符串长度len <= 110000 Output 每一行一

[hdu3068]最长回文(Manacher算法)

http://acm.hdu.edu.cn/showproblem.php?pid=3068 题目大意:求最长回文串的长度. 解题关键:Manacher算法 引用一个较好的解释 p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1; 可以这么说,这行要是理解了,那么马拉车算法基本上就没啥问题了,那么这一行代码拆开来看就是 如果mx > i, 则 p[i] = min(p[2 * id - i], mx - i) 否则, p[i] = 1 当 mx - i

HDU3068 最长回文(manacher模板

给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S两组case之间由空行隔开(该空行不用处理)字符串长度len <= 110000Output每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.Sample Input aaaa abab Sample Output