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

\(\text{template}\)

注意 z[1]=n,从下标 \(2\) 开始求 z!!

\(\text{Code}\)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

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

void getZ(char *s, int n, int *z) {
    for(int i = 2; i <= n; i++) z[i] = 0; z[1] = n;
    for(int i = 2, l = 0, r = 0; i <= n; i++) {
        if (i <= r) z[i] = min(z[i - l + 1], r - i + 1);
        while (i + z[i] <= n && s[z[i] + 1] == s[i + z[i]]) ++z[i];
        if (i + z[i] - 1 > r) r = i + z[i] - 1, l = i;
    }
}

void exkmp(char *s, int n, char *t, int m) {
    getZ(t, m, z);
    for(int i = 1, l = 0, r = 0; i <= n; i++) {
        if (i <= r) p[i] = min(z[i - l + 1], r - i + 1);
        while (i + p[i] <= n && t[p[i] + 1] == s[i + p[i]]) ++p[i];
        if (i + p[i] - 1 > r) r = i + p[i] - 1, l = i;
    }
}

int main() {
    scanf("%s%s", a + 1, b + 1), n = strlen(a + 1), m = strlen(b + 1), exkmp(a, n, b, m);
    LL ans = 0;
    for(int i = 1; i <= m; i++) ans ^= (LL)i * (z[i] + 1);
    printf("%lld\n", ans);
    ans = 0;
    for(int i = 1; i <= n; i++) ans ^= (LL)i * (p[i] + 1);
    printf("%lld\n", ans);
}
posted @ 2023-05-16 16:05  leiyuanze  阅读(23)  评论(0编辑  收藏  举报