[Template] KMP algorithm, fail tree

ACM template


table of Contents

KMP string

Video explanation by Xiao Ran

Substring: Select a continuous segment from the original string, which is the
prefix of the substring (including the empty string) : pre (s, k) pre(s,k)p r e ( s ,k ) is thesuffix of thesubstring formed by thefirstk characters ofs
: suf (s, k) suf(s,k)suf(s,k ) is a substring composed of s(k...n)
Any substring is a prefix of a certain suffix. The
longest common prefixlcp (s, t) lcp(s,t)lcp(s,t ) and the longest common suffixlcs (s, t) lcs(s,t)lcs(s,t)

周期: 0 < p < ∣ s ∣ 0<p<|s| 0<p<s s [ i ] = s [ i + p ] , ∀ i ∈ { 1 , 2 , … , ∣ s ∣ − p } s[i]=s[i+p], \forall i\in\{1,2,\dots,|s|-p\} s[i]=s[i+p],i{ 1,2,,sp } , meet the above conditions, calledppp is the period
Borderof s:0 <r <∣ s ∣ 0<r<|s|0<r<s p r e ( s , r ) = s u f ( s , r ) pre(s,r)=suf(s,r) p r e ( s ,r)=suf(s,r ) , meet the above conditions, callpre (s, r) pre(s,r)p r e ( s ,r ) is

the relationship betweenthe borderperiodof s and the border:pre (s, k) pre(s,k)p r e ( s ,k ) is the border⇔ \Leftrightarrow of s | s | - k | s | -ksk is
the transitivity ofthe periodic
border of s:①string s is the border of t, and string t is the border of r, then s is the border of r ②string
s is the border of r, and the string t (∣ t ∣> ∣ s ∣ | t|>|s|t>s ) is also the border of r, then s is the border of t, and
mb(s) represents the longest border of s. Then mb(s), mb(mb(s))... all the borders that constitute s

Given a pattern string S and a template string P, all strings only contain uppercase and lowercase English letters and Arabic numerals.

The template string P appears as a substring multiple times in the pattern string S.

Calculate the initial index (starting from 0) of all the positions of the template string P in the pattern string S.

#include<iostream>
using namespace std;
const int N=1000010;
int n,m;
char p[N],s[N];
int ne[N];
int main()
{
    
    
    cin>>n>>p+1>>m>>s+1;
    // 求ne过程看成两个相同的串匹配
    for(int i=2,j=0;i<=n;i++)
    {
    
    
        while(j&&p[i]!=p[j+1]) j=ne[j];
        if(p[i]==p[j+1]) j++;// i结尾能够匹配 1~j 那么ne[i]=j
        ne[i]=j;
    }
    // 当前需要判断是否匹配 p[j+1]?=s[i]
    for(int i=1,j=0;i<=m;i++)
    {
    
    
        while(j&&s[i]!=p[j+1]) j=ne[j];
        if(s[i]==p[j+1]) j++;
        if(j==n)
        {
    
    
            cout<<i-n<<' ';
            j=ne[j];
        }
    }
    return 0;
}

Fail mismatch tree

Concept and construction: Regarding next[i] as the parent node of point i , then the 0~N points can be connected into a tree through the next array, which satisfies the properties:

  • All ancestors of point i are borders with prefix pre(s,i)
  • Two points i and j without ancestor relationship have no border relationship

Connection: The process of calculating next[i] can be seen as: starting from j=fa[i-1] and going up continuously, find the first point that satisfies s[j+1]=s[i], and put point i Set the father to j+1

#include<string>
#include<iostream>
using namespace std;
const int N=1000010;
int ne[N];
int fa[N][21],dep[N];
string s;
int n;
int lca(int a,int b)
{
    
    
    if(dep[a]<dep[b]) swap(a,b);
    for(int k=20;k>=0;k--)
        if(dep[fa[a][k]]>=dep[b]) a=fa[a][k];
    if(a==b) return a;
    for(int k=20;k>=0;k--)
        if(fa[a][k]!=fa[b][k])
        {
    
    
            a=fa[a][k];
            b=fa[b][k];
        }
    return fa[a][0];
}
int main()
{
    
    
    cin>>s;
    n=s.size();
    s="."+s;
    dep[0]=1,dep[1]=2;
    fa[1][0]=0;
    for(int i=2,j=0;i<=n;i++)
    {
    
    
        while(j&&s[i]!=s[j+1]) j=ne[j];
        if(s[i]==s[j+1]) j++;
        ne[i]=j;
        // 构建失配树
        fa[i][0]=j;dep[i]=dep[j]+1;
        for(int k=1;k<=20;k++)
            fa[i][k]=fa[fa[i][k-1]][k-1];
    }
    int q;
    cin>>q;
    while(q--)
    {
    
    
        int a,b;
        cin>>a>>b;
        int pab=lca(a,b);
        // 注意本身是公共祖先的情况
        if(a==pab||b==pab) cout<<ne[pab]<<'\n';
        else cout<<pab<<'\n';
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/112724803
Recommended