试题描述

输入一个字符串S,输出S的最长连续回文子串长度。

输入
输入一个字符串S。
输出
输出S的最长连续回文子串长度
输入示例
abacbbc
输出示例
4
其他说明
1<=|S|<=1000000

这就是传说中的萌萌哒马拉车算法(manacher)啦

首先为了方便处奇偶两种情况,将S重新变成新的字符串T,如abacddc变成#a#b#a#c#d#d#c#

再次为了方便处理越界,将字符串首尾加一个奇怪的不匹配字符,如将abacddc变成~#a#b#a#c#d#d#c#`

请大家想一想这样的好处

考虑暴力算法,枚举回文串中心,暴力向两边匹配

rep(,n-) {
int t=;
while(s[i-t]==s[i+t]) t++;
ans=max(ans,t-);
}

这样是O(N^2),考虑优化

我们定义P[i]表示位置i的最长匹配长度,考虑利用之前的匹配信息。

这样就是p[i]=p[2*id-i]

这样就是p[i]=mx-i

写成代码就是这样

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
char s[maxn];
int p[maxn];
int solve(char* s2) {
int n=,id=,mx=,ans=;
for(int i=;s2[i]!='\0';i++) s[n++]='#',s[n++]=s2[i];
s[]='~';s[n++]='#';s[n++]='`';
rep(,n-) {
if(mx>i) p[i]=min(p[*id-i],mx-i);
else p[i]=;
while(s[i+p[i]]==s[i-p[i]]) p[i]++;
if(i+p[i]>mx) mx=i+p[i],id=i;
ans=max(ans,p[i]-);
}
return ans;
}
char s2[maxn];
int main() {
scanf("%s",s2);
printf("%d\n",solve(s2));
return ;
}

为什么是O(N)的呢?

因为算法只有遇到还没有匹配的位置时才进行匹配,已经匹配过的位置不再进行匹配,所以对于T字符串中的每一个位置,只进行一次匹配,所以Manacher算法的总体时间复杂度为O(n),其中n为T字符串的长度,由于T的长度事实上是S的两倍,所以时间复杂度依然是线性的。

补一个PAM的(以后不能装*,将”f[np]=to[k][c];to[p][c]=np;“i写成”f[to[p][c]=np]=to[k][c];“就会T飞,因为k可能等于p)

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
char ch[maxn];
struct PAM {
int cnt,last;
int to[maxn][],f[maxn],l[maxn];
PAM() {cnt=f[]=;l[]=-;}
void extend(int c,int n) {
int p=last;
while(ch[n]!=ch[n-l[p]-]) p=f[p];
if(!to[p][c]) {
int np=++cnt,k=f[p];l[np]=l[p]+;
while(ch[n]!=ch[n-l[k]-]) k=f[k];
f[np]=to[k][c];to[p][c]=np;
}
last=to[p][c];
}
int solve() {
int ans=;
rep(,cnt) ans=max(ans,l[i]);
return ans;
}
}sol;
int main() {
scanf("%s",ch+);int n=strlen(ch+);
rep(,n) sol.extend(ch[i]-'a',i);
printf("%d\n",sol.solve());
return ;
}

COJ977 WZJ的数据结构(负二十三)的更多相关文章

  1. COJ 1002 WZJ的数据结构(二)(splay模板)

    我的LCC,LCT,Splay格式终于统一起来了... 另外..这个形式的Splay是标准的Splay(怎么鉴别呢?看Splay函数是否只传了一个变量node就行),刘汝佳小白书的Splay写的真是不 ...

  2. [COJ0988]WZJ的数据结构(负十二)

    [COJ0988]WZJ的数据结构(负十二) 试题描述 输入 见题目,注意本题不能用文件输入输出 输出 见题目,注意本题不能用文件输入输出 输入示例 输出示例 数据规模及约定 1≤N≤1500,M≤N ...

  3. COJ967 WZJ的数据结构(负三十三)

    WZJ的数据结构(负三十三) 难度级别:C: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...

  4. COJ968 WZJ的数据结构(负三十二)

    WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...

  5. COJ 0967 WZJ的数据结构(负三十三)

    WZJ的数据结构(负三十三) 难度级别:E: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...

  6. COJ 0979 WZJ的数据结构(负二十一)

    WZJ的数据结构(负二十一) 难度级别:C: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你实现一个数据结构,完成这样的功能: 给你一个 ...

  7. [COJ0968]WZJ的数据结构(负三十二)

    [COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...

  8. [COJ0985]WZJ的数据结构(负十五)

    [COJ0985]WZJ的数据结构(负十五) 试题描述 CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R- ...

  9. [COJ0989]WZJ的数据结构(负十一)

    [COJ0989]WZJ的数据结构(负十一) 试题描述 给出以下定义: 1.若子序列[L,R]的极差(最大值-最小值)<=M,则子序列[L,R]为一个均匀序列. 2.均匀序列[L,R]的权值为S ...

随机推荐

  1. 将XML解析成DOM文档

    在支持html5的浏览其中,可以使用标准解析器DOMParser对象进行解析html或者xml等字符串 var data = '<div></div>'; var tmp = ...

  2. sed替换字符串时,使用正则表达式的注意事项

    sed的使用方法为: 使用单个模式替换:sed 's/pattern/replacement/flags' filename,例如echo 'abc' | sed 's/a/A/'-->Abc ...

  3. eclipse 启动后,啥也不干,就一直在loading descriptor for XXX (XXX为工程名),,其他什么操作都不能操作。 如下图所示,保存文件也无法保存。 这个怎么办?一年好几天,什么都干不了!!!!!

    解决办法: 解决办法是 断一下网就好了

  4. 59. 总结篇:数组中N(n=1,2,3)个只出现一次的数字[find N numbers which appear only once in array]

    [本文链接] http://www.cnblogs.com/hellogiser/p/find-n-numbers-which-appear-only-once-in-array.html [题目] ...

  5. Android Studio项目整合PullToRefresh的问题记录

    PullToRefresh下拉刷新在App中应用非常频繁,然而PullToRefresh是在ADT下开发完成的.如果要将其整合到Android Studio目录下的话颇费周折.前面的文章“Androi ...

  6. Android 和iOS 创建本地通知

    1 Android 中的发送本地通知的逻辑如下 先实例化Notification.Builder,再用builder创建出具体的Notification,创建时要指定好启动用的PendingInten ...

  7. ubuntu下java环境变量配置

    转自:http://blog.csdn.net/tenpage/article/details/7215810 如果是配置java环境,请参照这篇,更简单:在Ubuntu 12.04 LTS上安装JD ...

  8. touch详解

    touch事件 前言 一个触屏网站到底和传统的pc端网站有什么区别呢,交互方式的改变首当其冲.例如我们常用的click事件,在触屏设备下是如此无力. 手机上的大部分交互都是通过touch来实现的,于是 ...

  9. EZ的间谍网络(codevs 4093)

    由于外国间谍的大量渗入,学校安全正处于高度的危机之中.YJY决定挺身而作出反抗.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手 ...

  10. p235习题3