首页 > 其他分享 >manacher

manacher

时间:2023-07-29 09:14:16浏览次数:28  
标签:string int manacher 至少 对称点 maxl 回文

应用

O(n)求以每个节点为中心的回文串长度

原理

1、对S=“hshbvbhshb”,每个字符之间插入“#”,以便统一奇偶长度回文串。并在最前插入"^",左右扩展边界时才不会访问到-1,右边不用是因为自带"\0"。得到T="^#h#s#h#b#v#b#h#s#h#b#"

2、定义p[i]为T中i位为中心回文串半径,注意回文串不包括边界的"#"。然后我们愉快地发现p[i]就是S中回文串长度,而起点就是(i-p[i]-1)/2

3、最最最重要:如何求p[i]   利用回文串对称性质

假设我们已经知道i位前的p[],现回文串最右的右端点为R(注意R不在回文串中),其中心为C。i_m为i对于C对称点

若i不在C的回文串里,朴素

找到对称点回文半径3,那么i为回文半径至少为3,即至少有回文串"h#s#h"

为什么说至少:i回文右端"h"右接C的回文串外部,外部的情况是不确定的,是未知的。朴素地扩展一下,同时更新C,R

不至少的情况:i回文不右接外部,即p[i_m]<diff=R-i

上面说的至少也不准确,因为有i_m回文串超出C回文串的情况。因此p[i]至少为min(p[i_m],diff)

时间复杂度是怎么保证的呢?在每次朴素的时候,我们将R单调向右移动,最多移动n次

代码

const int MAX=2.2e7+10;
int p[MAX];
string s;
string pP(string s){//得到处理后字符串
    int n=s.length();
    if(!n)  return "$";
    string ret="$";
    for(int i=0;i<n;++i)
        ret+="#"+s.substr(i,1);
    ret+="#";
    return ret;
}string lP(string s){
    string T=pP(s);int len=T.length();
    int C=0,R=0;
    for(int i=1;i<len;++i){//忽略0位的"$"
        int i_m=C*2-i,diff=R-i;
        if(diff>=0){//i在C的回文串中
            if(p[i_m]<diff)  p[i]=p[i_m];
            else{//i_m回文超出或左接C回文
                p[i]=diff;
                while(T[i+p[i]+1]==T[i-p[i]-1]){
                    p[i]++;C=i;R=i+p[i];
                }//朴素扩展
            }
        }else{
            p[i]=0;
            while(T[i+p[i]+1]==T[i-p[i]-1]){
                p[i]++;C=i;R=i+p[i];
            }
        }
    }int maxl=0,cI=0;
    for(int i=1;i<len-1;++i)
        if(p[i]>maxl){maxl=p[i];cI=i;}
    return s.substr((cI-1-maxl)/2,maxl);
}//返回最长回文串
View Code

 格式好像崩了,就这样吧

标签:string,int,manacher,至少,对称点,maxl,回文
From: https://www.cnblogs.com/yswn/p/17589268.html

相关文章

  • Template <Manacher>
    #include<iostream>#include<string>#include<vector>usingnamespacestd;//O(n)计算字符串s的每个字符的最大回文半径,返回最长回文子串长度intManacher(strings){ //空字符串直接返回0if(s.length()==0)return0; //manacher扩展后串长度int......
  • manacher马拉车算法
    目录manacher算法相关资料manacher算法用于\(O(n)\)求解字符串中的最长回文子串相关资料马拉车算法(不懂问我)......
  • manacher 记录
    首先注意2*n的长度  mx:当前匹配到的最大长度即[1,mx]id:mx对应的中心点pi:s[i]为中心的回文串的最大长度, pi/2-1是半径() #include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;constintN=2.3*1E7;chars[N];c......
  • Manacher算法学习笔记
    Manacher算法是什么Manacher算法就是马拉车。Manacher算法就是用于解决回文子串的个数的。问题引入P3805:【模板】manacher算法题目大意给出一个只由小写英文字符\(\texttta,\textttb,\textttc,\ldots\texttty,\textttz\)组成的字符串\(S\),求\(S\)中最长回文串......
  • 单模字符串匹配算法(KMP, exKMP, manacher)
    约定:本文字符串均从\(1\)开始。模式串\(T\)的长度为\(n\),匹配串\(S\)的长度为\(m\)。1.KMP1.1前缀函数给定一个长度为\(n\)的字符串\(S\),其前缀函数被定义为一个长度为\(n\)的数组\(\pi\)。其中\(\pi_i\)被定义为:若子串\(S[1\cdotsi]\)有一对相等的真前......
  • hdu 5157(manacher+前缀和+树状数组)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5157解题思路:我们可以先用mancher算法对字符串进行处理,把以每个点为中心的回文串半径求出来,然后进行处理。加入对以p为中心的点,从p-r[i]+1~p都是回文串的开头,那么对于每个回文串(开头是j)只要记录结尾从1~j-1的回文串个数,我们可......
  • Manacher
    Manacher的几个模板模板一前后插入不等的特殊字符(不用写越界的判断条件)中间用#隔离(不用判断奇偶)#include<bits/stdc++.h>usingnamespacestd;constintN=22000005;chars[N],t[N];intcnt,mr,mid,len[N];voidbuild(){ cin>>s; t[++cnt]......
  • codeforces 159D D. Palindrome pairs( manacher+dp )
    题目链接:codeforces159D题目大意:给出一个字符出,求取这个字符串中互相不覆盖的两个回文子串的对数。题目分析:首先能够用manacher模板,因为这个算法处理的字符串的长度式奇数,所以我们首先将原字符串拓展,也就是用一个没有出现过的子串填充到每两个字符之间,首位也要添加,这样处理后得到......
  • 马拉车(manacher) & 回文自动机(PAM)
    读了徐安矣2023年集训队论文写的,对于差分性质和习题,我会在理解清楚之后再补充。本篇博客仅讨论前两种算法。首先,马拉车和回文自动机都是处理回文串问题的。但在此之前,学习一些更加简单的回文算法。小trick:把给定串的两头和缝隙插入相同字符,且在边界处用不同字符标记,使得长度为......
  • Manacher
    算法简介Manacher算法用于求解一串字符串中的最长回文子串的长度。如:abab的最长回文子串的长度为3。时间复杂度$O(n)$实现原理1.构造回文串有两种情况:情况1:abba,其对称轴在两字符中间情况2:abcba,其对称轴在中间字符上由于Manacher算法只能处理第二种情况,所以要......