P5410 【模板】擴充套件 KMP(Z 函式)

tomjobs發表於2020-11-11

在這裡插入圖片描述

思路:
擴充套件kmp模板題,程式碼來自XHT

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e7 + 7;
int n, m, z[maxn], p[maxn];
char a[maxn], b[maxn];

inline void Z(char *s, int n) {
    for (int i = 1; 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[i+z[i]] == s[z[i]+1]) ++z[i];
        if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
    }
}

inline void exkmp(char *s, int n, char *t, int m) {
    Z(t, m);
    for (int i = 1; i <= n; i++) p[i] = 0;
    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 && s[i+p[i]] == t[p[i]+1]) ++p[i];
        if (i + p[i] - 1 > r) l = i, r = i + p[i] - 1;
    }
}

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 ^= 1ll * i * (z[i] + 1);
    }
    printf("%lld\n",ans);
    ans = 0;
    for(int i = 1;i <= n;i++) {
        ans ^= 1ll * i * (p[i] + 1);
    }
    printf("%lld\n",ans);
    return 0;
}

相關文章