Manacher求最长回文

#1032 : 最长回文子串

时间限制:1000ms

单点时限:1000ms

内存限制:64MB

描述

小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

小Ho奇怪的问道:“什么叫做最长回文子串呢?”

小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

提示一 提示二 提示三 提示四

样例输入
3
abababa
aaaabaa
acacdas
样例输出
7
5
3

马拉车好写又好用

#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<algorithm>
#include<iostream>
typedef long long LL;
using namespace std;
#define maxn (int)2e6+3
int p[maxn];
char str[(maxn)>>1],s[maxn];
int manacher(char *str)
{
    int len=strlen(str);
    s[0]='$';s[1]='#';
    for(int i=0;i<=len;i++)
    {
        s[2*i+2]=str[i];
        s[2*i+3]='#';
    }
    int n=strlen(s);
    int r=0,tmp=1,ans=0;
    for(int i=1;i<n;i++)
    {
        if(r>i)p[i]=min(p[2*tmp-i],r-i);
        else p[i]=1;
        while(s[i+p[i]]==s[i-p[i]])p[i]++;
        if(p[i]>ans)ans=p[i];
        if(i+p[i]>r)
        {
            r=i+p[i];
            tmp=i;
        }
    }
    return ans-1;
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",str);
        printf("%d\n",manacher(str));
    }
    return 0;
}

Manacher求最长回文,布布扣,bubuko.com

时间: 2024-10-13 08:41:46

Manacher求最长回文的相关文章

HDU 4513 吉哥系列故事——完美队形II manacher求最长回文

题目来源:吉哥系列故事--完美队形II 题意:中文 思路:在manacher算法向两边扩展的时候加判断 保证非严格递减就行了 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100110; int a[maxn<<1]; int b[maxn<<1]; int dp[maxn<<1]; int

manacher求最长回文子串算法

原文:http://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号.比如 abba 变成 #a#b#b#a#, aba变成 #a#b#a#. 为了进一步减少编码的复杂度,可以在字符串的开始加入另一个特殊字符,这样就不用特殊处理越界问题,比如 @#a#b#a#(注意,下面的代码是用C语言写 就,由于C语言规范还要求字符串末尾有一个'\0'所以正好OK,但其

manacher求最长回文子串算法模板

#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> #include <string> #include <math.h> #include <stdlib.h> using namespace std; int p[maxn]; char s[maxn]; void manacher(char *s){//时间复杂度O(

HDU 4513 哥几个系列故事——形成完善II manacher求最长回文

标题来源:哥几个系列故事--形成完善II 意甲冠军:中国 思维:在manacher断 保证非严格递减即可了 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100110; int a[maxn<<1]; int b[maxn<<1]; int dp[maxn<<1]; int manacher

O(n) 求最长回文子串的 Manacher 算法

Manacher是一个可以在O(n)的时间内求出一个长度为n的字符串的算法. 以为回文子串有偶数长度,也有奇数长度,分别处理会很不方便. 所以在每两个字符中间插入一个无关字符,如‘#’,这样所有的回文子串都变为奇数长度. 两端在添加不同的无关字符防止匹配时越界. 如: abba 变成 $#a#b#b#a#& 预处理代码: void Prepare() { l = strlen(Str); S[0] = '$'; for (int i = 0; i <= l - 1; i++) { S[(i

[hdu3068 最长回文]Manacher算法,O(N)求最长回文子串

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文串并更新答案,复杂度O(N3). 枚举回文串的对称轴i,以及回文半径r,由i和r可确定一个子串,然后暴力判断即可.复杂度O(N2). 在上一步的基础上,改进判断子串是否是回文串的算法.记fi(r)=(bool)以i为对称轴半径为r的子串是回文串,fi(r)的值域为{0, 1},显然fi(r)是关于r

算法进阶之manacher算法 (求最长回文)

前几天bestcode做到一道字符串的题目,需要O(n)的回文,正好看到网上的manacher算法,于是来学习一发 进入正题: manacher算法 用法:一般用于求一个字符串的最大回文,操作过程中会记录以每个点为中心的回文半径,可用来进行其他操作 时间复杂度:O(n) 空间复杂度:记录字符串2*n,半径数组2*n 内容: 记p[i]为以i为中心的回文半径(aba中以b为中心的回文半径为2,那么如果是偶数个数的回文呢,比如abba?这里先讨论奇数,偶数后面再说,简单说就是用字符填充变成奇数) 因

后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a rather alarming anonymous letter. It states that the agent from the competing «Robots Unlimited» has infiltrated into “U.S. Robotics”. «U.S. Robots» s

manacher hihoCoder1032 最长回文子串

居然能够做到O(n)的复杂度求最长回文.,也是给跪了. 以下这个人把manacher讲的很好,,能够看看 http://blog.csdn.net/xingyeyongheng/article/details/9310555 我就照着他的代码敲了一遍贴了个模板.. #include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstd