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

求最长回文子串

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

转载:

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

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

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

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

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

代码如下:

 #include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=;
int n,w[maxn],wa[maxn],wb[maxn],wv[maxn];
int a[maxn],sa[maxn],rank[maxn],height[maxn],f[maxn][];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r,int *sa,int n,int m){
int i,j,p,*x=wa,*y=wb,*t;
for (i=;i<m;i++) w[i]=;
for (i=;i<n;i++) w[x[i]=r[i]]++;
for (i=;i<m;i++) w[i]+=w[i-];
for (i=n-;i>=;i--) sa[--w[x[i]]]=i;
for (p=,j=;p<n;m=p){
for (p=,i=n-j;i<n;i++) y[p++]=i;
for (i=;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
for (i=;i<m;i++) w[i]=;
for (i=;i<n;i++) w[wv[i]=x[y[i]]]++;
for (i=;i<m;i++) w[i]+=w[i-];
for (i=n-;i>=;i--) sa[--w[wv[i]]]=y[i];
for (t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
}
void calheight(int *r,int *sa,int n){
int i,j,k=;
for (i=;i<=n;i++) rank[sa[i]]=i;
for (i=;i<n;height[rank[i++]]=k)
for (k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
return;
}
void rmq(int *rank,int n){
int i,j;
memset(f,,sizeof(f));
for (i=;i<=n;i++) f[i][]=height[i];
for (j=;j<;j++)
for (i=;i+(<<j)-<=n;i++)
f[i][j]=min(f[i][j-],f[(<<(j-))+i][j-]);
return;
}
int get_rmq(int x,int y){
int a=rank[x],b=rank[y];
if (a>b) {int t=a; a=b; b=t;}
a++;
int t=int(log(double(b-a+))/log(2.00));
return min(f[a][t],f[b-(<<t)+][t]);
}
int main(){
char s[maxn];
cin >> s;
n=strlen(s);
int i,ans=,k=;
for (i=;i<n;i++) a[i]=s[i];
a[n]=;
for (i=;i<n;i++) a[i+n+]=s[n--i];
a[*n+]=;
da(a,sa,*n+,);
calheight(a,sa,*n+);
rmq(rank,*n+);
for (i=;i<n;i++){
int t=get_rmq(i,*n-i)*-;
if (t>ans)
{
ans=t;
k=i;
}
if (i>)
{
t=get_rmq(i,*n-i+)*;
if (t>ans)
{
ans=t;
k=i;
}
}
}
if (ans%!=) for (i=k-ans/;i<=k+ans/;i++) cout<<s[i];
else for (i=k-ans/;i<k+ans/;i++) cout<<s[i];
cout<<endl;
return ;
}

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. PuTsangTo-单撸游戏开发04 给角色添加基本动画

    一. 跳跃与移动的优化与完善 先给上一次的内容做一次补救,也就是上一次中还留存的,由于键盘按键事件的第一次回调与后续回调之间会间隔个小半秒带来的跳跃落地后动作延迟的情况. 最终的键盘按下回调的处理代码 ...

  2. Linux网络那点事

    跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 之前的之前说过网络自连接的配置(CentOS服务器网络配置:http://ww ...

  3. ajax VS websocket

    一. ajax VS websocket总结 http://blog.csdn.net/qiuhuanmin/article/details/50719114 二.用Websocket代替Ajax来开 ...

  4. Java进阶之内存管理与垃圾回收

    Java是在JVM所虚拟出的内存环境中运行的.内存分为栈(stack)和堆(heap)两部分.我们将分别考察这两个区域. 栈 在Java中,JVM中的栈记录了线程的方法调用.每个线程拥有一个栈.在某个 ...

  5. H5学习第四周

    本周.我们结束了HTML标签和css样式部分,开始了JS的学习.JS是的内容和css,html基本上没有什么联系而且它比较需要逻辑思考能力,所以要从新开始学习. 使用js的三种方式: 1.html标签 ...

  6. Struts2中there is no action mapped for acion name (/XXXXX)

    这里的问题出在配置struts.xml中,去掉配置中 namespace="/"属性 即可解决.不同的调用action的方式对namespace="/"属性有的 ...

  7. start with connect by prior 递归查询用法,很实用

    当开发过程需要查询上下级机构类似的树形机构,还有就是查询当前等级下的所有所属节点 这个子句主要是用于B树结构类型的数据递归查询,给出B树结构类型中的任意一个结点,遍历其最终父结点或者子结点. 先看原始 ...

  8. Load 数据1

    Druid 的load 数据分为两类 :批量load(历史数据) 和实时load(新数据) ,本文介绍批量load 数据 indexing 服务 批量load 数据需要用到indexing 服务,它是 ...

  9. 【one day one linux】好用的数据处理工具awk

    awk:好用的数据处理工具 取自<鸟哥私房菜>awk一节 应用:awk是以一行为一次的处理单位,将一行分成数个“字段”进行处理. #awk的命令格式 awk '条件类型1{动作1} 条件类 ...

  10. js的break语句,continue语句,return语句

    js的break语句,continue语句,return语句. 用的时候很容易混淆,有过一次泪奔的经历. break语句 break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch ...