F04【模板】扩展 KMP(Z 函数)

F04 扩展 KMP(Z 函数)_哔哩哔哩_bilibili

 

P5410 【模板】扩展 KMP/exKMP(Z 函数) - 洛谷

题目:给定文本串a和模式串b,求z函数和p函数。
z函数:模式串b 与 模式串b 的每个后缀的最长公共前缀(LCP)的长度
p函数:模式串b 与 文本串a 的每个后缀的最长公共前缀(LCP)的长度
a: aaabaa
b: aaba
z[1,2,3,4]={4 1 0 1}
p[1,2,3,4,5,6]={2 4 1 0 2 1}

// 扩展KMP O(|a|+|b|)
#include<bits/stdc++.h>
using namespace std;

const int N=2e7+5;
char a[N],b[N];
int la,lb,z[N],p[N];

void get_z(char*b){ //z函数
  z[1]=lb;
  for(int i=2,l,r=0;i<=lb;i++){
    if(i<=r) z[i]=min(z[i-l+1],r-i+1);
    while(b[1+z[i]]==b[i+z[i]]) z[i]++;
    if(i+z[i]-1>r) l=i,r=i+z[i]-1;
  }
}
void get_p(char*a,char*b){ //p函数
  for(int i=1,l,r=0;i<=la;i++){
    if(i<=r) p[i]=min(z[i-l+1],r-i+1);
    while(1+p[i]<=lb&&i+p[i]<=la&&b[1+p[i]]==a[i+p[i]]) p[i]++;
    if(i+p[i]-1>r) l=i,r=i+p[i]-1;  
  }
}
int main(){
  cin>>a+1>>b+1; //文本串a 模式串b
  la=strlen(a+1),lb=strlen(b+1);
  get_z(b);
  get_p(a,b);
  
  long long ans1=0,ans2=0;
  for(int i=1; i<=lb; i++) ans1^=1LL*i*(z[i]+1);
  for(int i=1; i<=la; i++) ans2^=1LL*i*(p[i]+1);
  cout<<ans1<<"\n"<<ans2;
  return 0;
}

 

posted @ 2022-04-14 08:44  董晓  阅读(1651)  评论(0)    收藏  举报