COJ977 WZJ的数据结构(负二十三)
试题描述
|
输入一个字符串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的数据结构(负二十三)的更多相关文章
- COJ 1002 WZJ的数据结构(二)(splay模板)
我的LCC,LCT,Splay格式终于统一起来了... 另外..这个形式的Splay是标准的Splay(怎么鉴别呢?看Splay函数是否只传了一个变量node就行),刘汝佳小白书的Splay写的真是不 ...
- [COJ0988]WZJ的数据结构(负十二)
[COJ0988]WZJ的数据结构(负十二) 试题描述 输入 见题目,注意本题不能用文件输入输出 输出 见题目,注意本题不能用文件输入输出 输入示例 输出示例 数据规模及约定 1≤N≤1500,M≤N ...
- COJ967 WZJ的数据结构(负三十三)
WZJ的数据结构(负三十三) 难度级别:C: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...
- COJ968 WZJ的数据结构(负三十二)
WZJ的数据结构(负三十二) 难度级别:D: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有 ...
- COJ 0967 WZJ的数据结构(负三十三)
WZJ的数据结构(负三十三) 难度级别:E: 运行时间限制:7000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,完成以下功能: 给定一个大 ...
- COJ 0979 WZJ的数据结构(负二十一)
WZJ的数据结构(负二十一) 难度级别:C: 运行时间限制:5000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 请你实现一个数据结构,完成这样的功能: 给你一个 ...
- [COJ0968]WZJ的数据结构(负三十二)
[COJ0968]WZJ的数据结构(负三十二) 试题描述 给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着.请你设计一个数据结构,回答M次操作. 1 x:将节点x上的灯拉一次,即亮变 ...
- [COJ0985]WZJ的数据结构(负十五)
[COJ0985]WZJ的数据结构(负十五) 试题描述 CHX有一个问题想问问大家.给你一个长度为N的数列A,请你找到两个位置L,R,使得A[L].A[L+1].…….A[R]中没有重复的数,输出R- ...
- [COJ0989]WZJ的数据结构(负十一)
[COJ0989]WZJ的数据结构(负十一) 试题描述 给出以下定义: 1.若子序列[L,R]的极差(最大值-最小值)<=M,则子序列[L,R]为一个均匀序列. 2.均匀序列[L,R]的权值为S ...
随机推荐
- process vs thread
process vs thread http://blog.csdn.net/mishifangxiangdefeng/article/details/7588727 6.进程与线程的区别:系统调度是 ...
- MyEclipse内存溢出问题解决方法
tomcat从1.7换到1.6,一直报这个错:java.lang.reflect.InvocationTargetException 解决方法: 加入: -server -Xms512m -Xmx20 ...
- Android下利用Bitmap切割图片
在自己自定义的一个组件中由于需要用图片显示数字编号,而当前图片就只有一张,上面有0-9是个数字,于是不得不考虑将其中一个个的数字切割下来,需要显示什么数字,只需要组合一下就好了. 下面是程序的关键代码 ...
- Android实现电子邮箱客户端
本文主要讲述了安卓平台上利用QQ邮箱SMTP协议,POP3协议发送与接收消息的实现 发送邮件核心代码 import java.security.Security; import java.util.D ...
- 安卓向服务器发送List数据
第一步: 首先写一个自定义的JavaBean,以UserInfo.java为例,需要实现对象序列化的接口,因为之后输出流对象需要实现输出可序列化的对象.不这样的话,后续时发送时会报异常 package ...
- 使用jquery制作可视化的组织结构
组织结构是做项目里面经常用到的,但是要做成可视化的效果比较少,多数使用树结构来表示,但是对于客户来说不是太直观.可以用jOrgChart来实现.如下图的效果,这样就比较直观. 首先你要去下载jOrgC ...
- A session had already been started - ignoring session_start() 解决方法
A session had already been started - ignoring session_start() --已经存在一个session 打开了 -- 忽略sessioon_star ...
- cJSON: 一个用c写的一个简单好用的JSON解析器
转自:http://blog.csdn.net/chenzhongjing/article/details/9188347 下载地址: http://sourceforge.net/projects/ ...
- 【poj2828】Buy Tickets 线段树 插队问题
[poj2828]Buy Tickets Description Railway tickets were difficult to buy around the Lunar New Year in ...
- 【JNI】锅炉压力监测器
public class MainActivity extends Activity { private MyProgressBar pb; static{ System.loadLibrary(&q ...