bzoj 2565 manacher

2682. 【WC2012选拔12.17】最长双回文串 (Standard IO)

Time Limits: 2000 ms  Memory Limits: 524288 KB

Description

顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。

  输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。

Input

一行由小写英文字母组成的字符串S。

Output

一行一个整数,表示最长双回文子串的长度。

Sample Input

baacaabbacabb

Sample Output

12

Data Constraint

Hint

【样例说明】

从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。

【数据范围】

对于10%的数据,2≤|S|≤103。

  对于30%的数据,2≤|S|≤104。

  对于100%的数据,2≤|S|≤105。

思路:

先做一遍MANACHER,然后枚举分界点(为#)

那么以这个点为分界的最长双回文串会由最左边的能覆盖到这个点的串和最右边的能覆盖到这个点的串组成

那么扫两遍求出每个点最左和最右能覆盖到它的回文串中心。(就是反过来求以每个点为中心的回文串能覆盖哪些点

然后枚举即可

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

char s[200011];
int r[200011],lm[200011],rm[200011];
int i,n,x,z,q,len,j;
char c;

void Read()
{
    while(c=getchar(),c<‘a‘||c>‘z‘);
    s[++n]=‘#‘;
    s[++n]=c;
    while(c=getchar(),c>=‘a‘&&c<=‘z‘){
        s[++n]=‘#‘;
        s[++n]=c;
    }
    s[++n]=‘#‘;
}

void Manacher()
{
    int i,len,l,k;
    len=0;
    for(i=1;i<=n;i++){
        if(len<i){
            l=0;
            while(s[i-l]==s[i+l]&&i-l>=1&&i+l<=n)l++;
            r[i]=l;
        }
        else{
            l=min(len-i+1,r[k+k-i]);
            while(s[i+l]==s[i-l]&&i-l>=1&&i+l<=n)l++;
            r[i]=l;
        }
        if(i+r[i]-1>len){
            len=i+r[i]-1;
            k=i;
        }
    }
}

int main()
{
    Read();
    Manacher();
    r[0]=0;
    len=0;
    for(i=1;i<=n;i++){
        if(i+r[i]-1>len){
            for(j=len+1;j<=i+r[i]-1;j++)lm[j]=i;
            len=i+r[i]-1;
        }
        if(len==n)break;
    }
    len=n+1;
    for(i=n;i>=1;i--){
        if(i-r[i]+1<len){
            for(j=i-r[i]+1;j<=len-1;j++)rm[j]=i;
            len=i-r[i]+1;
        }
        if(len==1)break;
    }
    for(i=1;i<=n;i++)if(s[i]==‘#‘){
        z=(rm[i]-i+1)*2-1+(i-lm[i]+1)*2-1-1;
        if(z/2>q)q=z/2;
    }
    printf("%d\n",q);
}

bzoj 2565 manacher

时间: 2024-08-08 22:06:59

bzoj 2565 manacher的相关文章

BZOJ 2565 回文串-Manacher

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2565 题意:中文题 思路:定义L[i],R[i].表示以i为左端点/右端点时,最长回文串长度.那么答案就是L[i]+R[i]的最大值.问题转化为怎么求L[i],R[i].我们通过用Manacher可以求出以i为中心的最长回文串半径.然后再通过暴力+剪枝的方法对于每一个i和对应的最长半径求更新L[i],R[i]. #include<iostream> #include<cstdio

【题解】Casting Spells LA 4975 UVa 1470 双倍回文 SDOI 2011 BZOJ 2342 Manacher

首先要吐槽LRJ,书上给的算法标签是"有难度,需要结合其他数据结构",学完Manacher才发现几乎一裸题 题目的意思是问原串中有多少个wwRwwR这样的子串,其中wR表示w的反串 比较容易看出来,wwRwwR本身是一个回文串,wwR也是一个回文串 最裸的暴力是,我们枚举每一个回文串,然后判断这个回文串的左半边是不是也是个回文串 然后我们考虑用Manacher 我们考虑Manacher的工作原理,是在充分利用原先的信息的前提下,不重复,不遗漏的枚举每个回文串 也就是说,在Manache

BZOJ 2565 最长双回文串 Hash+二分

题目大意:给定一个字符串,求一个最长的子串,该字串可以分解为两个回文子串 傻逼的我又忘了Manacher怎么写了= = 无奈Hash+二分吧 首先将字符串用分隔符倍增,然后求出以每个点为中心的最长回文半径 然后考虑两个回文串怎么合并成一个 我们发现图中以i为中心的回文串和以j为中心的回文串合并后长度恰好为(j-i)*2 能合并的前提是以两个点为中心的回文串有交点 那么对于每个j我们要求出有交点的最左侧的i 维护一个后缀min随便搞搞就可以了 #include <cstdio> #include

bzoj 2565: 最长双回文串

Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为"abc",逆序为"cba",不相同).输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串. Input 一行由小写英文字母组成的字符串S. Output 一行一个整数,表示最长双回文子串的长度. Sample Input baacaabbacabb Sample Output 12 HINT

【BZOJ】【2565】最长双回文串

Manacher算法 找出一个最长子串S=X+Y,且X和Y都是回文串,求最长的长度是多少…… 同时找两个串明显很难搞啊……但是我们可以先找到所有的回文串!在找回文串的同时我们可以预处理出来l[i]和r[i]分别表示从 i 这个位置开始向左/右最长的回文串有多长,那么我们枚举两个回文串的分割点更新答案即可. 1 /************************************************************** 2 Problem: 2565 3 User: Tunix

Part.5【马拉车&amp;扩展KMP】

Manacher(马拉车)是一种求最长回文串的线性算法,复杂度O(n).网上对其介绍的资料已经挺多了的,请善用搜索引擎. 而扩展KMP说白了就是是求模式串和主串的每一个后缀的最长公共前缀[KMP更像是一个自动机] 题目: POJ 1159: Palindrome 求原字符串最少增加几个字符后可变成回文串,相当于求最长回文子序列的长度. 解法:直接求串S和反转串Sr的最长公共子序列. #include <cstdlib> #include <cstdio> #include <

回文相关算法

Manacher AC BZOJ 2565 1 #include <cstdio> 2 #include <fstream> 3 #include <iostream> 4 5 #include <cstdlib> 6 #include <cstring> 7 #include <algorithm> 8 #include <cmath> 9 10 #include <queue> 11 #include &l

目前的字符串

Aho-Corasick automaton:BZOJ4820[bzoj2754][SCOI2012]喵星球上的点名后缀数组:BZOJ4310 跳蚤manacher: BZOJ3160万径人踪灭Palindromic Tree:bzoj4044Bzoj3676:[Apio2014]回文串 bzoj 1559 ** ac+jvchengBZOJ1195:[HNOI2006]最短母串 ** ac+jvchengbzoj 1692 * sabzoj 1031 * sabzoj 3796 ** sa+k

回文树总结

回文树介绍看这 : 点击 回文树 首先,回文树有何功能?假设我们有一个串S,S下标从0开始,则回文树能做到如下几点: 1.求串S前缀0~i内本质不同回文串的个数(两个串长度不同或者长度相同且至少有一个字符不同便是本质不同)2.求串S内每一个本质不同回文串出现的次数3.求串S内回文串的个数(其实就是1和2结合起来)4.求以下标i结尾的回文串的个数 模板: const int MAXN = 100005 ; const int N = 26 ; struct Palindromic_Tree { /