题意
给出 A A A、 B B B两个字符串,至多将 A A A串修改一个字符,使得 A [ 1.. k ] A[1..k] A[1..k]是 B B B的子串且 k k k最大。
思路
枚举 B B B的开头,二分 L C P LCP LCP,然后用字符串 h a s h hash hash判断。设 L C P ( A , B [ i . . m ] ) LCP(A,B[i..m]) LCP(A,B[i..m])为 l e n len len,显然是要修改 A [ l e n + 1 ] A[len+1] A[len+1]的,再求出 L C P ( A [ l e n + 1 ] , B [ i + l e n + 1 ] ) LCP(A[len+1],B[i+len+1]) LCP(A[len+1],B[i+len+1]),那么答案就为这两个 L C P LCP LCP相加再加上修改的 1 1 1。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
char a[50001], b[50001];
unsigned long long p[50001], fa[50001], fb[50001];
int la, lb, ans;
int find(int l1, int l2) {
int l = 0, r = std::min(la - l1 + 1, lb - l2 + 1);
while (l < r) {
int mid = l + r + 1 >> 1;
if (fb[l2 + mid - 1] - fb[l2 - 1] * p[mid] == fa[l1 + mid - 1] - fa[l1 - 1] * p[mid]) l = mid;
else r = mid - 1;
}
return l;
}
int main() {
scanf("%s", a + 1);
scanf("%s", b + 1);
la = strlen(a + 1);
lb = strlen(b + 1);
p[0] = 1;
for (int i = 1; i <= la; i++) fa[i] = fa[i - 1] * 131 + a[i] - 96;
for (int i = 1; i <= lb; i++) fb[i] = fb[i - 1] * 131 + b[i] - 96, p[i] = p[i - 1] * 131;
for (int i = 1; i <= lb; i++) {
int res = find(1, i);
if (i + res - 1 == lb || res == la) {
ans = std::max(ans, res);
continue;
}
int x = find(res + 2, res + i + 1);
ans = std::max(ans, res + x + 1);
}
printf("%d", ans);
}