试题描述

输入一个字符串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. HDOJ 1233

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  2. maven3 junit4 spring3 jdk8 :junit一直报错,害的我几个星期都是这个错,你妹的!

    [org.springframework.test.context.junit4.SpringJUnit4ClassRunner]SpringJUnit4ClassRunner constructor ...

  3. iOS 中的frame,bounds,center,transform关联

    这里有一篇好文章 http://www.winddisk.com/2012/06/07/transform/ 先看几个知识点,UIView 的frame,bounds,center,transform ...

  4. Mobile first! Wijmo 5 + Ionic Framework之:Hello World!

    本教程中,我们用Wijmo 5 和 Ionic Framework实现一个Mobile的工程:Hello World. Ionic是什么? Ionic是一个HTML5框架.免费.开源,用于帮助生成hy ...

  5. 转数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7696085 ,转载请注明出处!本文着重介绍sharding切分策略,如果你对数据库sh ...

  6. js将map转成数组

    //根据资源的ID去查找 this.classArray = []; for(var c in this.comboData.classId){ this.classArray.push({ text ...

  7. mybatis整合spring 之 基于接口映射的多对一关系

    转载自:http://my.oschina.net/huangcongmin12/blog/83731 mybatis整合spring 之  基于接口映射的多对一关系. 项目用到俩个表,即studen ...

  8. opencv学习笔记(三)基本数据类型

    opencv学习笔记(三)基本数据类型 类:DataType 将C++数据类型转换为对应的opencv数据类型 OpenCV原始数据类型的特征模版.OpenCV的原始数据类型包括unsigned ch ...

  9. GCD的基本使用

    // // ViewController.m // gcd队列与函数 // // Created by 诠释 on 15/9/3. // Copyright (c) 2015年 诠释. All rig ...

  10. LINUX下安装TeamViewer

    https://www.teamviewer.com/zhcn/download/linux/ [root@ok teamviewer]# yum install -y teamviewer_11.0 ...