http://wenku.baidu.com/link?url=WFI8QEEfzxng9jGCmWHoKn0JBuHNfhZ-tKTDMux34CeY8UNUwLVPeY5HA3TyoKU2XegXFPifjunarW-YmXFrP_m8-3DEhBu1MHxHghHqD0O

这篇讲的比较好,准备一个模板,做题的时候用。

  1. void manacher()
  2. {
  3. int mx = , id = ;
  4. for (int i = ; i <= n; i++)
  5. {
  6. if (mx > i)
  7. p[i] = min(p[id * - i], mx - i);
  8. else
  9. p[i] = ;
  10. while (a[i + p[i]] == a[i - p[i]])
  11. p[i]++;
  12. if (mx < p[i] + i)
  13. {
  14. mx = p[i] + i;
  15. id = i;
  16. }
  17. }
  18. }

这个初始化的时候是从1开始的

  1. for (int i = ; i <= n; i++)
  2. {
  3. a[i * - ] = str[i];
  4. a[i * ] = -;
  5. }

其中p表示回文半径,str是原串,a表示添加字符之后的串

两个例题:

hdu5340

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <cstdlib>
  6. #include <algorithm>
  7.  
  8. using namespace std;
  9. typedef long long LL;
  10. const int maxn = ;
  11. char str[maxn], a[maxn<<];
  12. int p[maxn<<], L[maxn<<], R[maxn<<];
  13. int n;
  14. void manacher()
  15. {
  16. int mx = , id = ;
  17. for (int i = ; i <= n; i++)
  18. {
  19. if (mx > i)
  20. p[i] = min(p[id * - i], mx - i);
  21. else
  22. p[i] = ;
  23. while (a[i + p[i]] == a[i - p[i]])
  24. p[i]++;
  25. if (mx < p[i] + i)
  26. {
  27. mx = p[i] + i;
  28. id = i;
  29. }
  30. }
  31. }
  32. bool solve()
  33. {
  34. for (int i = ; i <= L[]; i++)
  35. {
  36. for (int j = ; j <= R[]; j++)
  37. {
  38. int l = L[i] + ;
  39. int r = R[j] - ;
  40. if (r - l <= )
  41. continue;
  42. int mid = (l + r) / ;
  43. if (p[mid] >= r - mid + )
  44. return true;
  45. }
  46. }
  47. return false;
  48. }
  49. int main()
  50. {
  51. int T;
  52. scanf("%d", &T);
  53. while (T--)
  54. {
  55. scanf("%s", str + );
  56. n = strlen(str + );
  57. for (int i = ; i <= n; i++)
  58. {
  59. a[i * - ] = str[i];
  60. a[i * ] = '#';
  61. }
  62. n = n * - ;
  63. a[] = '$';
  64. a[n + ] = '@';
  65. manacher();
  66. memset(L, , sizeof(L));
  67. memset(R, , sizeof(R));
  68. for (int i = ; i <= n; i++)
  69. {
  70. int l = i - p[i] + ;
  71. int r = i + p[i] - ;
  72. if (l == )
  73. L[++L[]] = r;
  74. if (r == n)
  75. R[++R[]] = l;
  76. }
  77. if (solve())
  78. puts("Yes");
  79. else
  80. puts("No");
  81. }
  82. return ;
  83. }

hdu5371

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <cstdlib>
  6. #include <algorithm>
  7. using namespace std;
  8. typedef long long LL;
  9. const int maxn = ;
  10. int str[maxn], a[maxn<<];
  11. int p[maxn<<];
  12. int n;
  13. void manacher()
  14. {
  15. int mx = , id = ;
  16. for (int i = ; i <= n; i++)
  17. {
  18. if (mx > i)
  19. p[i] = min(p[id * - i], mx - i);
  20. else
  21. p[i] = ;
  22. while (a[i + p[i]] == a[i - p[i]])
  23. p[i]++;
  24. if (mx < p[i] + i)
  25. {
  26. mx = p[i] + i;
  27. id = i;
  28. }
  29. }
  30. }
  31. void print()
  32. {
  33. for (int i = ; i <= n; i++)
  34. printf("%d ", p[i]);
  35. }
  36. int main()
  37. {
  38. int T;
  39. int kase = ;
  40. scanf("%d", &T);
  41. while (T--)
  42. {
  43. scanf("%d", &n);
  44. for (int i = ; i <= n; i++)
  45. scanf("%d", &str[i]);
  46. for (int i = ; i <= n; i++)
  47. {
  48. a[i * - ] = str[i];
  49. a[i * ] = -;
  50. }
  51. int m = n;
  52. n = n * - ;
  53. a[] = -;
  54. a[n + ] = -;
  55. manacher();
  56. int ans = ;
  57. for (int i = ; i <= n; i += )
  58. p[i] /= ;
  59. for (int i = ; i <= n; i += )
  60. {
  61. if (p[i] * < ans)
  62. continue;
  63. for (int j = p[i]; j * >= ans; j--)
  64. {
  65. if (p[i + j * ] >= j)
  66. {
  67. ans = max(ans, j * );
  68. break;
  69. }
  70. }
  71. }
  72. printf("Case #%d: %d\n", ++kase, ans);
  73. }
  74. return ;
  75. }

Manacher算法求回文半径的更多相关文章

  1. HDU 5371(2015多校7)-Hotaru&#39;s problem(Manacher算法求回文串)

    题目地址:HDU 5371 题意:给你一个具有n个元素的整数序列,问你是否存在这样一个子序列.该子序列分为三部分,第一部分与第三部分同样,第一部分与第二部分对称.假设存在求最长的符合这样的条件的序列. ...

  2. SPOJ STC02 - Antisymmetry(Manacher算法求回文串数)

    http://www.spoj.com/problems/STC02/en/ 题意:给出一个长度为n的字符串,问其中有多少个子串s可以使得s = s按位取反+翻转. 例如样例:11001011. 10 ...

  3. hdu5340—Three Palindromes—(Manacher算法)——回文子串

    Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  4. 马拉车算法——求回文子串个数zoj4110

    zoj的测评姬好能卡时间.. 求回文子串的个数:只要把p[i]/2就行了: 如果s_new[i]是‘#’,算的是没有中心的偶回文串 反之是奇回文串 /* 给定两个字符串s,t 结论:s,t不相同的第一 ...

  5. 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 ...

  6. Manacher算法求解回文字符串

    Manacher算法可以在\(O(N)\)时间内求解出一个字符串的所有回文子串(正反遍历相同的字串). 注:回文串显然有两种,一种是奇数长度,如abczcba,有一个中心字符z:另外一种是偶数个长度, ...

  7. 马拉车算法——求回文串起点hdu3294

    #include<bits/stdc++.h> using namespace std; #define maxn 500005 int p[maxn]; ]; int start; in ...

  8. Manacher算法 - 求最长回文串的利器

    求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...

  9. Manacher算法——求最长回文子串

    首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...

随机推荐

  1. 那些年被我坑过的Python——摩拳擦掌(第三章)

    集合类型: 集合类型中的元素是唯一的! 集合的定义与赋值: set_1 = set([1, 3, 5, 7, 2]) set_2 = set([2, 4, 6, 8, 3]) 集合的运算操作 # 交集 ...

  2. 升级Python至2.7.8,并安装django

    1:下载Python-2.7.8.tgz2:步骤:tar -zxvf Python-2.7.8.tgzcd Python-2.7.8./configure -h --查看configure选项./co ...

  3. 关于SQL server的一些知识点

    关于怎么打开xp_cmdshell的方法: exec sp_configure 'show advanced option',1reconfiguregoexec sp_configure 'xp_c ...

  4. 提高Order by语句查询效率的两个思路

    提高Order by语句查询效率的两个思路 2011-03-01 13:07 水太深 ITPUB 字号:T | T 在MySQL数据库中,Order by语句的使用频率是比较高的.但是众所周知,在使用 ...

  5. Parencodings

    Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two diff ...

  6. 看奢侈品Prada如何使用物联网

    这是峰哥在一家国际顶级商学院听课的笔记.这是个巨变的时代,有趣的时代. 一 PRADA在纽约的旗舰店.每件衣服上都有RFID码.每当一个顾客拿起一件PRADA进试衣间,RFID会被自动识别,试衣间里的 ...

  7. 【转】 java中HashMap详解

    原文网址:http://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap详解 HashMap 和 HashSet 是 Jav ...

  8. CodeForces 591A

    题目链接: http://codeforces.com/problemset/problem/591/A 题意: a,b两个相距L距离,两个分别以p,q速度从左右两个端点出发,每次相遇后,又以原来的速 ...

  9. Codeforces Round #326 (Div. 1) - C. Duff in the Army 树上倍增算法

    题意:一个n个点的数, m个人住在其中的某些点上, 每个人的标号1-m, 询问u-v 路径上标号前a个人,并输出标号,a < 10. 作法, 利用倍增, ID[j][i] 表示i到i的第2^j个 ...

  10. 动态规划——线性dp

    我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...