\(\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);
}
标签:LG,int,text,char,getZ,P5410,KMP,strlen
From: https://www.cnblogs.com/leiyuanze/p/17405952.html