失配树学习笔记

编程入门 行业动态 更新时间:2024-10-27 21:12:31

<a href=https://www.elefans.com/category/jswz/34/1477682.html style=失配树学习笔记"/>

失配树学习笔记

失配树,是一种奇妙的数据结构,它利用 KMP、LCA 解决求两前缀的最长公共 Border 的问题。

首先介绍一下什么是 Border,我们知道 nxt 数组是前后缀相同的最大长度,Border 相当于是 nxt 数组的弱化版,只是去掉了“最大”的限制。

我们考虑如何建立一棵失配树(fail 树),对于每一个长度为 i i i 的前缀,我们预处理出它的 nxt,然后按照 i i i 指向 nxt[i],即 nxt[i] 是 i i i 的爹。

对于两个前缀的最长 Border,我们只需要对于两个区间的 i i i、 j j j 求出它们的 LCA 即可。这里需要注意一个坑,如果 i i i 和 j j j 的 LCA 是他们中的一个,那么我们要把 LCA 上提一步,即返回 f[i][0]f[j][0](返回他们的父亲)。


练手板子题

代码如下:

#include <bits/stdc++.h>
using namespace std;const int maxn=1e6+5;
char s[maxn];
int f[maxn][25],dep[maxn];int lca(int x,int y)
{if(dep[x]<dep[y]) swap(x,y);for(int i=20;i>=0;i--) if(dep[f[x][i]]>=dep[y]) x=f[x][i];if(x==y) return f[x][0];for(int i=20;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];return f[x][0];
}int main()
{scanf("%s",s+1);int len=strlen(s+1);f[0][0]=f[1][0]=0;dep[0]=0;dep[1]=1;for(int i=1,j=0;i<=len;i++){while(j&&s[i+1]!=s[j+1]) j=f[j][0];if(s[i+1]==s[j+1]) j++;f[i+1][0]=j,dep[i+1]=dep[j]+1;}int m;cin>>m;for(int j=1;j<=20;j++) for(int i=1;i<=len;i++) f[i][j]=f[f[i][j-1]][j-1];while(m--){int p,q;cin>>p>>q;cout<<lca(p,q)<<endl;}return 0;
}

更多推荐

失配树学习笔记

本文发布于:2023-12-05 13:21:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1664343.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:失配   学习笔记

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!