洛谷P5829 【失配树】 (KMP算法)

这是一篇关于洛谷P5829题目的博客,主要讨论如何利用KMP算法和失配树解决给定字符串的最长公共前缀后缀问题。博客介绍了算法思路,包括构建失配树来表示每个位置的前缀和后缀匹配长度,并使用倍增法求解最长公共边界(LCA)。文章最后提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:

给定一个串 S,定义 border 为它的非本身的既是它的前缀又是它的后缀的字符串,每次询问 i,j 求出前 i 个和前 j 个字符的最长公共 border 长度。

算法分析:

根据题目的描述,会发现这道题本质上是 KMP,求出每一个点的前缀和后缀匹配的长度,设为 kmp 数组。然后就是这道题的精髓。

这里需要建一个失配树,也就是每一个点的 kmp 数组向这个点连一条边。(个人感觉跟 AC 自动机的 fail 树有异曲同工之妙。)这时会发现,会建成一个树,父亲节点就是 kmp 数组的值,儿子节点就是该点。

最后,题目的要求相当于求两个点的 LCA,用倍增求即可。

注意细节,如果这两个点本身就有 border 关系,那么需要输出 dep 小的点的父亲节点。也很好实现,把倍增中的中途 x=y 返回删去,直接最后返回即可。

具体细节看代码吧。

总代码:

#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch&#
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值