exkmp(Z函数)
exkmp(Z函数)#
题意:
给定两个字符串 A
B
,要求出两个数组:
B
与B
的每一个后缀的LCP
长度 (next)B
与A
的每一个后缀的LCP
长度 (extend)
求 以及
算法:
图中 S
表示 A
,T
表示 B
nxt[]
即 next[]
,ext[]
即 extend
现在已求得 nxt[1~n]
以及 ext[1~i-1]
,要求 ext[i]
设置变量 a
、p
,p
代表以 a
为起始位置的字符匹配成功的最右边界
那么我们可以得到:A[a~p]=B[0~p-a]
现在 A[i]
对应 B[i-a]
若 i+nxt[i-a]<p
,如上,那么此时 ext[i]=nxt[i-a]
若 i+nxt[i-a]=p
,如上,那么此时我们可以从 A[p]
和 B[p-a]
往后匹配
若 i+nxt[i-a]>p
,如上,那么此时我们可以让 ext[i]=p-i
时间复杂度:
code:
#include <bits/stdc++.h>
using namespace std;
const int N=2e7+5;
int nxt[N],ext[N];
inline void get_next(char *B,int m){
int a=0,p=0;
nxt[0]=m;
for(int i=1;i<m;++i){
if(i>=p||i+nxt[i-a]>=p){
if(i>=p)
p=i;
while(p<m&&B[p]==B[p-i])
++p;
nxt[i]=p-i;
a=i;
}
else
nxt[i]=nxt[i-a];
}
}
inline void get_extend(char *A,char *B,int n,int m){
int a=0,p=0;
for(int i=0;i<n;++i){
if(i>=p||i+nxt[i-a]>=p){
if(i>=p)
p=i;
while(p<n&&A[p]==B[p-i])
++p;
ext[i]=p-i;
a=i;
}
else
ext[i]=nxt[i-a];
}
}
int n,m;
char A[N],B[N];
inline void Z(){
get_next(B,m);
get_extend(A,B,n,m);
}
signed main(){
scanf("%s%s",A,B);
n=strlen(A),m=strlen(B);
Z();
long long a=0;
for(int i=0;i<m;++i) a^=1ll*(i+1)*(nxt[i]+1);
cout<<a<<endl;
a=0;
for(int i=0;i<n;++i) a^=1ll*(i+1)*(ext[i]+1);
cout<<a<<endl;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!