题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1297

求最长回文子串

典型的后缀数组的入门题目,但是可以用更简单的方法解决,毕竟数据量比较小啊

转载:

题目大意:给出一个字符串,求它的连续最长回文子串。

分析:这题数据规模不大(n<=1000),所以直接暴力可以解决。不过如果数据规模大了,暴力就不行了。这里介绍后缀数组的做法。

首先,枚举回文子串的中心所在位置。这里要分回文串长度为奇数和偶数两种情况考虑。这两个问题均可以转化为求一个后缀和一个倒着写的后缀的最长公共前缀。

具体地,将原串与反着写之后的原串相连,中间以一个特殊字符隔开。这个特殊字符只要不是0号,不影响后缀的排序,就没有问题。(不能是0是因为我的倍增算法要求除了字符串的最后一位以外,其它位不能为0,否则会出错)然后算出height数组。两个后缀的最长公共前缀为两个后缀排序之后,它们之间的串的height值的最小值。这个可以自己举个具体例子好好体会。用st算法求解rmq问题即可。

********************************************************************************************************************************************************************************************************************

代码如下:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cmath>
  4. using namespace std;
  5. const int maxn=;
  6. int n,w[maxn],wa[maxn],wb[maxn],wv[maxn];
  7. int a[maxn],sa[maxn],rank[maxn],height[maxn],f[maxn][];
  8. int cmp(int *r,int a,int b,int l){
  9. return r[a]==r[b]&&r[a+l]==r[b+l];
  10. }
  11. void da(int *r,int *sa,int n,int m){
  12. int i,j,p,*x=wa,*y=wb,*t;
  13. for (i=;i<m;i++) w[i]=;
  14. for (i=;i<n;i++) w[x[i]=r[i]]++;
  15. for (i=;i<m;i++) w[i]+=w[i-];
  16. for (i=n-;i>=;i--) sa[--w[x[i]]]=i;
  17. for (p=,j=;p<n;m=p){
  18. for (p=,i=n-j;i<n;i++) y[p++]=i;
  19. for (i=;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
  20. for (i=;i<m;i++) w[i]=;
  21. for (i=;i<n;i++) w[wv[i]=x[y[i]]]++;
  22. for (i=;i<m;i++) w[i]+=w[i-];
  23. for (i=n-;i>=;i--) sa[--w[wv[i]]]=y[i];
  24. for (t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
  25. x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
  26. }
  27. return;
  28. }
  29. void calheight(int *r,int *sa,int n){
  30. int i,j,k=;
  31. for (i=;i<=n;i++) rank[sa[i]]=i;
  32. for (i=;i<n;height[rank[i++]]=k)
  33. for (k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
  34. return;
  35. }
  36. void rmq(int *rank,int n){
  37. int i,j;
  38. memset(f,,sizeof(f));
  39. for (i=;i<=n;i++) f[i][]=height[i];
  40. for (j=;j<;j++)
  41. for (i=;i+(<<j)-<=n;i++)
  42. f[i][j]=min(f[i][j-],f[(<<(j-))+i][j-]);
  43. return;
  44. }
  45. int get_rmq(int x,int y){
  46. int a=rank[x],b=rank[y];
  47. if (a>b) {int t=a; a=b; b=t;}
  48. a++;
  49. int t=int(log(double(b-a+))/log(2.00));
  50. return min(f[a][t],f[b-(<<t)+][t]);
  51. }
  52. int main(){
  53. char s[maxn];
  54. cin >> s;
  55. n=strlen(s);
  56. int i,ans=,k=;
  57. for (i=;i<n;i++) a[i]=s[i];
  58. a[n]=;
  59. for (i=;i<n;i++) a[i+n+]=s[n--i];
  60. a[*n+]=;
  61. da(a,sa,*n+,);
  62. calheight(a,sa,*n+);
  63. rmq(rank,*n+);
  64. for (i=;i<n;i++){
  65. int t=get_rmq(i,*n-i)*-;
  66. if (t>ans)
  67. {
  68. ans=t;
  69. k=i;
  70. }
  71. if (i>)
  72. {
  73. t=get_rmq(i,*n-i+)*;
  74. if (t>ans)
  75. {
  76. ans=t;
  77. k=i;
  78. }
  79. }
  80. }
  81. if (ans%!=) for (i=k-ans/;i<=k+ans/;i++) cout<<s[i];
  82. else for (i=k-ans/;i<k+ans/;i++) cout<<s[i];
  83. cout<<endl;
  84. return ;
  85. }

ural 1297. Palindrome的更多相关文章

  1. URAL 1297 Palindrome 后缀数组

    D - Palindrome Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  2. 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome

    题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...

  3. Manacher Ural 1297 Palindrome

    1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB The “U.S. Robots” HQ has just received a ...

  4. Ural 1297 Palindrome(Manacher或者后缀数组+RMQ-ST)

    1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The “U.S. Robots” HQ has just received a ...

  5. URAL - 1297 Palindrome —— 后缀数组 最长回文子串

    题目链接:https://vjudge.net/problem/URAL-1297 1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB ...

  6. ural 1297 Palindrome(Manacher模板题)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 求最长回文子串. http://acm.timus.ru/problem.aspx ...

  7. URAL 1297 Palindrome(后缀数组+ST表)

    [题目链接] http://acm.timus.ru/problem.aspx?num=1297 [题目大意] 求最长回文子串,并输出这个串. [题解] 我们将原串倒置得到一个新的串,加一个拼接符将新 ...

  8. URAL 1297 Palindrome 最长回文子串

    POJ上的,ZOJ上的OJ的最长回文子串数据量太大,用后缀数组的方法非常吃力,所以只能挑个数据量小点的试下,真要做可能还是得用manacher.贴一下代码 两个小错,一个是没弄懂string类的sub ...

  9. Ural 1297 Palindrome 【最长回文子串】

    最长回文子串 相关资料: 1.暴力法 2.动态规划 3.中心扩展 4.Manacher法 http://blog.csdn.net/ywhorizen/article/details/6629268 ...

随机推荐

  1. 关于CO中的processRequest和processFormRequest的区别

    在OAF开发中会有许多的CO,而一般情况下CO中的有两个基本的方法那就是processRequest和processFormRequest,processRequest是页面执行初始化的时候执行的方法 ...

  2. python学习随笔(一)

    我是为记录学习python的过程而开通了博客,希望以后自己能看看,也希望能分享一些给初学者. 话不多说,开始第一篇. (一)python解释器. python2和3,现在python2是主流,但是py ...

  3. jPaginate 一个非常好用的分页插件

    之前报馆项目用的前端框架easyui,还是用不太习惯,因此换了一个框架,最近为此找分页插件,偶然间看见一个非常好用的分页插件JPaginate Paginate是基于jquery的分页插件,非常轻量, ...

  4. 使用$.post和action或servlet交互 URL出现 http://localhost:8080/../[object%20Object] 错误的问题解决

    使用$.post时,如下所示: $.post({ url : "./test/ajaxTest", }); 控制台报:There is no Action mapped for n ...

  5. Snapman设计中的思考

    Snapman主页:http://www.snapman.xyz 原文链接地址:http://www.snapman.xyz/newsitem/277785310​   feiren工作室主要研究人类 ...

  6. com.android.ide.common.process.PrecessException:org.gradle.process....finished with non-zero exit value 1

    1.问题描述: 如图,在生成apk文件时出现如下错误, 2.原因分析: 我在网上搜了很多类似的问题,但试了又试也没有解决.然后我想上次编译时都没有出错,应该是最近的操作导致的错误. 3.解决办法: 把 ...

  7. 1129: 零起点学算法36——3n+1问题

    1129: 零起点学算法36--3n+1问题 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 4541 ...

  8. MFC使用SQLite 学习系列 一: SQLITE_MISUSE错误

    一 为什么要选择SQLite 由于使用文本文件来记录测试数据,速度越来越慢的问题,经过园友推荐,使用了SQLite来进行数据的存储,再次感谢园友@LightSmaile. 关于这个问题,可以参考一下上 ...

  9. React-Native 之 项目实战(五)

    前言 本文 有配套视频,可以酌情观看. 文中内容因各人理解不同,可能会有所偏差,欢迎朋友们联系我讨论. 文中所有内容仅供学习交流之用,不可用于商业用途,如因此引起的相关法律法规责任,与我无关,如文中内 ...

  10. 【转】JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    转自:http://www.cnblogs.com/ysw-go/ JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 ...