首页 > 其他分享 >Manacher 学习笔记

Manacher 学习笔记

时间:2024-03-09 17:11:19浏览次数:27  
标签:Manacher 复杂度 笔记 学习 对称中心 text 长度 回文

\(\text{Manacher}\) 学习笔记

定义

所谓回文串,指的是对于一个字符串 \(s\),若它的长为 \(n\),下标从 \(1\) 到 \(n\),如果 \(\forall i\in [1,n],s_i=s_{n+1-i}\),那么字符串 \(s\) 是一个回文串。

给定一个字符串 \(s\),求解它总共的回文子串个数。对于这一类问题的求解,我们发现,因为一个字符串的回文串最差是 \(O(n^2)\) 个,因此,我们貌似没有什么好的方法去优化算法的复杂度。但是,我们可以换一种更加紧凑的统计方式。

我们认为对于一个字符串 \(s\) 的子串 \(s[i\dots j]\),它的对称中心为 \(\lfloor\frac{i+j+1}{2}\rfloor\),那么我们可以统计对于每一个对称中心,长度为奇数、偶数的字符串分别有多少个,记为 \(d_1,d_2\),将两个数组中的所有值相加起来的结果即为答案。

这样统计的正确性是显然的,那么问题就在于如何求解了。

实现

暴力枚举

首先,对于 \(d_1,d_2\) 有一个性质:对于一个对称中心 \(i\),假设共有 \(k\) 个以它为中心的回文串,那么这些回文串的右端点一定是 \(i,i+1,\cdots,i+k-1\)。

最容易想到的方法无疑于暴力枚举,对于每一个对称中心,向两边枚举,直到两端不相同,将统计到的答案记入数组中,这样的复杂度是 \(O(n^2)\) 的。

\(\text{Manacher}\)

与暴力枚举不同的是,\(\text{Manacher}\) 致力于找到对于一个对称中心 \(i\),通过之前已经求解出的 \(d_1\) 数组,通过较优的复杂度处理出对应的结果。

我们考虑枚举到 \(i\) 时,整个字符串中右端点最靠右的回文串的下标范围为 \([l,r]\)。当 \(i\le r\) 时,我们可以得知 \(s_i=s_{l+r-i}\)。这是回文串的定义,更普遍的,\(\forall j\in[i-r,r-i],s_{i+j}=s_{l+r-i-j}\)。因为这两个位置是回文串 \([l,r]\) 的对应位置。现在我们目光聚集于以 \(i\) 为对称中心的回文串,我们发现 \(s_{i+j}=s_{i-j}\) 成立当且仅当 \(s_{l+r-i-j}=s_{l+r-i+j}\),这等价于两个位置关于 \(l+r-i\) 对称的点相等,那么我们发现,\(l+r-i\) 为对称中心的回文串有多少个,那么以 \(i\) 对称中心的回文串就理论有多少个。

为什么是理论多少个,因为当以 \(l+r-i\) 为对称中心的最长回文串超出了最右回文串的范围时,便不能保证答案的正确性,因为此时的 \(s_{l+r-i-j}\ne s_{i+j}\)。所以我们需要取 \(\min(d_1[l+r-i],r-i+1)\) 作为初始的最长长度,接着不断向两侧暴力拓展。

当 \(i>r\) 时,对称中心不在回文串中,因此只能暴力。

接着考虑复杂度的问题,对于 \(i\le r\) 的情况,容易证明不会将 \(k\) 增加。而对于 \(i>r\) 的情况,\(k\) 增加多少,就会将最右回文串向右移动多少位,因为最右回文串的右端点不会减小,并且最大为 \(n\),因此复杂度是 \(O(n)\) 的。

以上的讨论均针对长度为奇数的回文串,长度为偶数的回文串的思路类似。两者代码不同,但我们可以通过一个预处理,在一个基本相同的时间复杂度内用相同的代码求解。

考虑将所有的回文串的长度均变为奇数的方法:在字符串的开头、结尾和任意两个字符串之间均添加一个相同字符,如 \(\#\),这样原来长度为 \(n\) 的回文串的长度会变为 \(2n+1\),一定为奇数。此时可以只通过求解长度为奇数的回文串得到正确答案。值得注意的是,如此处理完成后,回文串 \(s\) 和回文串 \(\#s\#\) 在原串中对应的回文串相等,因此应将答案整体除以 \(2\)。更具体的,设 \(\text{Manacher}\) 处理出的数组为 \(d\) ,那么 \(d_1\) 与对应的 \(d\) 的关系为 \(d=2d_1\),\(d_2\) 与对应的 \(d\) 的关系为 \(d=2d_2+1\)。

代码

void Manacher(){
    int l=0,r=-1;//初始化
    for(int i=0;i<n;i++){
        int k=(i>r)?1:min(d[l+r-i],r-i+1);//判断已知最长回文串的长度
        while(i-k>=0&&i+k<n&&s1[i-k]==s1[i+k])k++;//暴力枚举
        d[i]=k--;//记录答案
        if(i+k>r){
            l=i-k;
            r=i+k;
        }//更新最右回文串
    }
    return ;
}

应用

最长回文子串

之前讲解了利用后缀数组 \(O(n\log n)\) 求解的办法,接下来讲解更为迅猛的 \(\text{Manacher}\) 法。

在我们求解出 \(d\) 数组后,我们容易得到以每一个位置为对称中心的最长回文子串的长度:对于长度为奇数的回文串,它的最长长度为 \(2d_1-1=d-1\);对于长度为偶数的回文串,它的最长长度为 \(2d_2=d-1\)。因此对 \(d\) 数组的值取最大后将答案减 \(1\) 即可。复杂度是 \(O(n)\) 的。

后记

事实上,不只是对回文串,对具有回文串类似的性质,即满足 \(\forall i\in[1,n],\text{Check}(s_i,s-n+1-i)=\text{True}\) 的定义,都可以利用 \(\text{Manacher}\) 求解。

标签:Manacher,复杂度,笔记,学习,对称中心,text,长度,回文
From: https://www.cnblogs.com/DycBlog/p/18062988

相关文章

  • 如何理解计算机类论文、机器学习论文、人工智能AI论文中的“soft”和“hard”呢?
    如何理解计算机类论文、机器学习论文、人工智能AI论文中的“soft”和“hard”呢?最近在看论文中总看到带有“soft”和“hard”的专业术语(terminology),一般二者都是作为对比进行出现的,那么问题就是在英文的计算机类论文的表达中这个“soft”和“hard”的区别点是什么?其实这个答案......
  • DP学习笔记
    Part1:DP的本质相信每个同学,都曾经有过被DP虐的经历。大部分同学在初学DP的时候,总是见一道题背过一道题,最后基本上是学会所有常见的套路,然后开始套模板。然而,随着层次的提升,这种文科生的思维就不够用了——毕竟谁会在IOI上傻乎乎地出个石子合并或者是多重背包呢?这样,我们......
  • manacher
    P3805【模板】manacher算法题意给定一个字符串,求所有字串中的最长回文串。思路暴力肯定过不了,如果在一个已经求出来的回文串中知道左半边,也肯定知道右半边,那么设\(d_i\)为以\(i\)为中心的回文串(奇数长度)的最长半径,那么在一个回文串\([l,r]\)中,知道\(d_{l+(r-i)}(......
  • CF1635F 笔记
    好题啊。题意给定\(n\)个二元组\((x_i,w_i)\),保证\(x\)升序。有\(m\)个询问\([l,r]\),对于每个询问求出:\[\min\limits_{l\lei<j\ler}(x_j-x_i)\cdot(w_i+w_j)\]题解一个精妙的结论:设\(L_i\)表示\(i\)左边第一个满足\(w_j\lew_i\)的\(j\),\(R_......
  • MYSQL学习笔记22: 多表查询
    多表查询单表查询查询emp表select*fromemp;查询dept表select*fromdept;笛卡尔积(全组合)#emp表有4条记录,dept表有6条记录#笛卡尔积有4*6=24条记录select*fromemp,dept;消除无效的笛卡尔积(emp和dept通过dept_id连接)select*fromemp,deptw......
  • 神州笔记本 win11 节能模式 供电不足 自动关机
    刚刚买了一个神州笔记本没几天,用着用着就出现问题了。本人使用电脑有个极为不好的习惯,那就是会一次性打开特别多的应用,然后不关,一直留着,这个习惯虽然不好但也是一直没有啥问题的,不过最近换了个新的笔记本就出现了问题。神州笔记本开启省电模式:之所以开这个模式其实并不是为......
  • P5416 笔记
    前置知识:线段树分治。题意给定\(n\)个节点的树,每个节点有一个二元组集合\(S_i\)。这个集合有一个限制:\(S_i\)一定是\(S_{fa_i}\)中删除一个二元组或者加一个二元组,并且加进来的二元组互不相同。现在有\(m\)个询问,每个询问给出\(k,h\)表示查询\(\min\limits_{(x,c......
  • 腾讯视频号直播卖货学习第五课-直播爆品三大特征
    腾讯视频号直播卖货学习第五课-直播爆品三大特征1满足泛用户需求1)视频号04+女性较多,转化以女性为主80%,一二三线占比60%+2)熟龄姐姐的需求保养,健康,家庭生活,教育,休闲娱乐,心里安慰,性价比等。3)城市中年大叔的需求:健康送礼收藏新奇特社交谈资休闲娱乐 2有认知也有教育空......
  • 无模型的强化学习方法
    无模型的强化学习算法学习「强化学习」(基于这本教材,强烈推荐)时的一些总结,在此记录一下。动态规划算法需要马尔可夫决策过程是已知的(状态转移函数、奖励函数已知),智能体不用真正地与环境互动也能在「理性」世界里求得最优策略。现实通常并非如此,环境已知恰恰是很少见的。所以这里......
  • Java学习笔记——第十天
    面向对象高级(一)staticstatic是一个关键字,义为静态,可以修饰成员变量和成员方法。static修饰成员变量成员变量的分类类变量(静态成员变量):有static修饰的成员变量,它们属于类,在计算机里只有一份,会被类的全部对象共享。实例变量(对象成员变量):无static修饰的成员变量,属于每个对象,每......