exkmp(Z函数)

exkmp(Z函数)#

题意

给定两个字符串 A B,要求出两个数组:

  • BB 的每一个后缀的 LCP 长度 (next)
  • BA 的每一个后缀的 LCP 长度 (extend)

xori=0n1i×(nxti+1) 以及 xori=0n1i×(exti+1)

算法

图中 S 表示 AT 表示 B

nxt[]next[]ext[]extend

现在已求得 nxt[1~n] 以及 ext[1~i-1],要求 ext[i]

设置变量 app 代表以 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

时间复杂度O(|A|+|B|)

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;
}

作者:Into_qwq

出处:https://www.cnblogs.com/into-qwq/p/16437070.html

版权:本作品采用「qwq」许可协议进行许可。

posted @   Into_qwq  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示