后缀数组 - 求最长回文子串 + 模板题 --- 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 ...
随机推荐
- C#人爱学不学9[C#5.0异步实例+WPF自己的MVVM Async应用 1/12]
文章摘要: 1. 通过简单DEMO.让读者理解Task和Task<T> 学习过程中,掌握async和await 2. 理解同步和异步的执行 3. Task.Factory.Start ...
- 解决mint17-linux里chrome一搞就弹出“登陆密钥环”的框框
摘自:https://sites.google.com/site/easylinuxtipsproject/tips#TOC-Make-the-keyring-password-on-your-com ...
- LeetCode: Lowest Common Ancestor of a Binary Search Tree 解题报告
https://leetcode.com/submissions/detail/32662938/ Given a binary search tree (BST), find the lowest ...
- 迁移SQL SERVER 数据库实例
由于某些原因,需要将2个数据库实例合并为1个,也就是说要把其中的一台迁移到另外一台上面. 背景介绍 :下面的B,C代表2个实例,要把B中相关东西迁移到C实例上面.其中B上面有一部分的同步是从另外一台服 ...
- 15.6.8-sql小技巧
取月头月尾: declare @someDay datetime,@firstDay datetime,@endDay datetime set @someDay='2015.2.2' ,) ,) s ...
- freemarker springmvc配置异常
异常信息 java.lang.IllegalAccessError: tried to access method freemarker.ext.servlet.AllHttpScopesHashMo ...
- Java开发者值得关注的7款新工具
云计算.大数据地快速发展催生了不少热门的应用及工具.作为老牌语言Java,其生态圈也出来了一些有关云服务.监控.文档分享方面的工具.本文总结了7款较新的Java工具,大家不妨看下. 1. JClari ...
- SQL Server 数据库操作类
/// <summary> /// SQLServerHelper的摘要说明. /// </summary> public class SQLServerHelper { pu ...
- DotNetBar RibbonControl控件office2007风格
在使用DotNetBar RibbonControl控件的时候如果想吧效果做成下图这种效果 把主窗体继承Office2007RibbonForm 然后要删除删除styleManager1 才会出现上图 ...
- 通过 Storyboard 快速搭建一系列连贯性的视图控制器
此例子只是一个简单的 Demo,这里没有过多介绍如何去实现,网上有很多关于 Storyboard 技术的介绍,请自行搜索. 效果如下: iPhone 5s iPhone 6 iPhone 6 ...