扩展KMP算法

P5410 【模板】扩展 KMP(Z 函数) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

来学了一下扩展KMP,改了四道晚自习的代码,今晚终于过了,我真的会谢,一些小细节问题

//扩展z函数(kmp扩展)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e7+10;
int z[N],p[N];
char a[N],s[N];
void get_z(char *s,int n)
{
    z[1] = n;
    for(int i = 2,l,r = 0;i <= n;i++)
    {
        if(i <= r)z[i] = min(z[i-l+1],r - i + 1);
        while(s[1+z[i]] == s[i+z[i]]) z[i]++;
        if(i+z[i]-1 > r) l = i,r = i+z[i]-1;
    }
}

void get_p(char *s,int n,char *a,int m)
{
    for(int i = 1,l,r = 0;i <= m;i++)//这里的边界是m!!!!!
    {
        if(i <= r)p[i] = min(z[i-l+1],r - i + 1);
        while(1+p[i] <= n && i+p[i] <= m && s[1+p[i]] == a[i+p[i]]) p[i]++;
        if(i+p[i]-1 > r) l = i,r = i+p[i]-1;
    }
}


signed main()
{
    ios::sync_with_stdio(false),cin.tie(0);//一定要取消同步流
    cin>>a+1>>s+1;
    int m = strlen(a+1);
    int n = strlen(s+1);

    get_z(s,n);
    get_p(s,n,a,m);
    ll ans1 = 0,ans2 = 0;
    for(int i = 1;i <= n;i++) ans1 ^= 1ll * i * (z[i]+1);
    for(int i = 1;i <= m;i++) ans2 ^= 1ll * i * (p[i]+1);
    cout<<ans1<<endl<<ans2; 


    return 0;
}

 kmp和扩展kmp的区别就在

KMP专门是前缀与后缀的比较!

而扩展KMP是整个串和最右端的串比较!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值