后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
1297. Palindrome
Memory Limit: 16 MB
In addition, it is reasonable to assume that the agent will be sending a very long message, so John has simply to find the longest message satisfying the mentioned property.
Input
Output
Sample
input |
---|
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA |
output |
ArozaupalanalapuazorA |
Mean:
给你一个字符串,让你输出字符串的最长回文子串。
analyse:
求最长回文串有很多方法,最经典的莫过于Manacher算法,时间复杂度O(n)。
这里就主要介绍一下用后缀数组的方法。
用后缀数组怎么求回文串呢?
原理和上一篇求最长公共子序列一样,我们把s1反转后接到s1后面得到S串,那么s1的最长回文串必定存在于S中,我们只需要求一下S的height数组,然后寻找来自于不同的两个串的height[i]的最大值,然后记录一下开始位置和长度,最后输出即可。
Time complexity:O(nlogn)
Source code:
Suffix Arrays:
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-05-09-21.22
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define LL long long
#define ULL unsigned long long
using namespace std;
const int MAXN=;
//以下为倍增算法求后缀数组
int wa[MAXN],wb[MAXN],wv[MAXN],Ws[MAXN];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}
/**< 传入参数:str,sa,len+1,ASCII_MAX+1 */
void da(const char *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) Ws[i]=;
for(i=; i<n; i++) Ws[x[i]=r[i]]++;
for(i=; i<m; i++) Ws[i]+=Ws[i-];
for(i=n-; i>=; i--) sa[--Ws[x[i]]]=i;
for(j=,p=; p<n; j*=,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<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) Ws[i]=;
for(i=; i<n; i++) Ws[wv[i]]++;
for(i=; i<m; i++) Ws[i]+=Ws[i-];
for(i=n-; i>=; i--) sa[--Ws[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;
}
int sa[MAXN],Rank[MAXN],height[MAXN];
/**< str,sa,len */
void calheight(const char *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++);
// Unified
for(int i=n;i>=;--i) ++sa[i],Rank[i]=Rank[i-];
}
char s1[MAXN],s2[MAXN];
int main()
{
while(~scanf("%s",s1))
{
int l1=strlen(s1);
strcat(s1,"{");
strcpy(s2,s1);
for(int i=;i<l1;++i) s1[i+l1+]=s2[l1-i-];
int len=strlen(s1);
da(s1,sa,len+,);
calheight(s1,sa,len);
int sta=,maxLen=,l,r;
for(int i=;i<=len;++i)
{
l=min(sa[i]-,sa[i-]-);
r=max(sa[i]-,sa[i-]-);
if((l<l1&&r>l1) && (len-r==l+height[i]))
{
if(height[i]>maxLen)
maxLen=height[i],sta=l;
else if(height[i]==maxLen)
sta=min(sta,l);
}
}
for(int i=sta,j=;j<maxLen;++i,++j)
printf("%c",s1[i]);
puts("");
}
return ;
}
Manacher:
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-09-12-15.41
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define max(a,b) (a>b?a:b)
using namespace std;
typedef long long(LL);
typedef unsigned long long(ULL);
const double eps(1e-8);
/** O(n)内求出所有回文串
*原串 :abaaba
*Ma串 :.,a,b,a,a,b,a,
*Mp[i]:Ma串中,以字符Ma[i]为中心的最长回文子串的半径长度(包括Ma[i],也就是把回文串对折后的长度).
****经过对原串扩展处理后,将奇数串的情况也合并到了偶数的情况(不需要考虑奇数串)
*/
const int MAXN=;
char Ma[MAXN*],s[MAXN];
int Mp[MAXN*],Mplen;
void Manacher(char s[],int len)
{
int le=;
Ma[le++]='.';
Ma[le++]=',';
for(int i=;i<len;++i)
{
Ma[le++]=s[i];
Ma[le++]=',';
}
Mplen=le;
Ma[le]=;
int pnow=,pid=;
for(int i=;i<le;++i)
{
if(pnow>i)
Mp[i]=min(Mp[*pid-i],pnow-i);
else
Mp[i]=;
for(;Ma[i-Mp[i]]==Ma[i+Mp[i]];++Mp[i]);
if(i+Mp[i]>pnow)
{
pnow=i+Mp[i];
pid=i;
}
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie();
while(~scanf("%s",s))
{
Manacher(s,strlen(s));
int maxLen=,idx=;
for(int i=;i<Mplen;++i)
{
if(Mp[i]>maxLen)
maxLen=Mp[i],idx=i;
}
for(int i=(idx-maxLen+)/,j=;j<maxLen-;++i,++j)
printf("%c",s[i]);
puts("");
// cout<<maxLen-1<<endl;
}
return ;
}
后缀数组 - 求最长回文子串 + 模板题 --- ural 1297的更多相关文章
- hdu 3068 最长回文(manachar求最长回文子串)
题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- Manacher模板( 线性求最长回文子串 )
模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...
- Manacher算法 O(n) 求最长回文子串
转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
- manacher算法求最长回文子串
一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...
- 求最长回文子串,O(n)复杂度
最长回文子串问题-Manacher算法 最长回文串问题是一个经典的算法题. 0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 假设一个字符串正着读和反着读是一样的,那它就是回 ...
- manacherO(n)求最长回文子串 hihocoder1032
原文地址:https://segmentfault.com/a/1190000003914228 http://blog.csdn.net/synapse7/article/details/189 ...
随机推荐
- ubuntu 16.04下安装oracle jdk 1.7
网上搜索了下,知道了大概,不能用apt装了,oracle也不再提供deb包了.只能下tar.gz包自己装. 先下载下来jdk:http://www.oracle.com/technetwork/jav ...
- 出现Assertion failure in -[***** layoutSublayersOfLayer:]
在自定义的view中使用了[self layoutIfNeeded]方法,在iOS8\9上都没有错误,但是在iOS7上出现了页面错乱,解决方案就是在自定义的view里面添加如下代码: + (void) ...
- ffrpc的php客户端lib
摘要: ffrpc 是c++异步通讯库,使用ffrpc可以非常容易的构建服务器程序.为了使用方便,ffrpc提供了python.php的客户端lib,这样使用php于c++构建的server也是顺手拈 ...
- 【书单】book list
正在看: [泡沫经济学].(日)野口悠纪雄 数学模型--姜启源 R in action Programming with R Scrapy Parallel R 准备看: Advanced.A ...
- python string.py 源码分析 三:maketrans
l = map(chr, xrange(256)) #将ascii转为字符串 _idmap = str('').join(l) del l # Construct a translation stri ...
- 【Android】如何实现ButterKnife
如何实现ButterKnife ButterKnife的原理简述 示例代码ButterKnifeProcedure Pluggable Annotation Processing 注解处理器 Java ...
- [Tip] 如何在BeyondCompare中忽略不重要的区别.
在使用BeyondCompare时,有时需要忽略一些不重要的区别,下面的链接教你如何通过定义语法元素来实现这个功能. http://www.scootersoftware.com/support.ph ...
- php报错: PHP Warning: PHP Startup: memcache: Unable to initialize module
在mac上通过brew 安装php的memcache扩展(brew install php56-memcache)后运行 ~ php -mPHP Warning: PHP Startup: mem ...
- ubuntu14.04服务版/etc/init.d/smbd restart无效的解决方法
刚装的ubuntu14.04配置完smbd发现service或者/etc/init.d/smbd restart都不显示任何输出,也没起作用 echo $?输出1,查看脚本发现 if init_is_ ...
- Oracle数据库入门——常用的数据字典
一.oracle数据字典主要由以下几种视图构成:1.user视图以user_为前缀,用来记录用户对象的信息 2.all视图以all_为前缀,用来记录用户对象的信息及被授权访问的对象信息 3.dba视图 ...