题目大意
给定文本串 $S$ 和模式串 $T$,对每个位置进行匹配,得到失配次数。
统计此失配次数,计算前缀和。
分析
我是没料到 HDOJ 没有 M_PI,CE 了几发。
FFT 字符串匹配模板题,我在 ZAFU Wiki 中讲过,即对每个字符卷积。
#include "template/basic/complex.hpp"
const int maxn = 1 << 20;
using img = Complex<double>;
using poly_t = vector<img>;
poly_t w;
#include "template/poly-fft/fft_init.hpp"
#include "template/poly-fft/fft.hpp"
char a[maxn], b[maxn];
int sum[maxn], ans[maxn];
char ch[] = "0123456789*";
int main() {
w = fft_init(maxn);
int ttt = rr();
while (ttt--) {
int n = rr(), m = rr();
fill(sum, sum + m + n + 12, 0);
fill(ans, ans + m + 12, 0);
int lim = getlim(m, n);
scanf("%s %s", b, a);
int tsum = 0;
for (int i = 0; i < m - 1; i++) {
tsum += b[i] == '*';
tsum += a[i] == '*';
}
tsum += a[m - 1] == '*';
reverse(a, a + m + 1);
for (int k = 0; k <= 10; k++) {
poly_t SS(lim);
for (int i = 0; i < n; i++)
SS[i].x = b[i] == ch[k];
for (int i = 1; i <= m; i++)
SS[i].y = a[i] == ch[k];
fft(SS);
for (int i = 0; i < lim; i++)
SS[i] = SS[i] * SS[i];
ifft(SS);
if (k == 10) {
for (int i = 0; i <= m + n; i++)
sum[i] -= int(SS[i].y / 2 + 0.5);
} else {
for (int i = 0; i <= m + n; i++)
sum[i] += int(SS[i].y / 2 + 0.5);
}
}
for (int i = m; i <= n; i++) {
tsum += (b[i - 1] == '*') - (b[i - m - 1] == '*');
int tans = tsum + sum[i];
ans[m - tans]++;
}
tsum = 0;
for (int i = 0; i <= m; i++) {
tsum += ans[i];
printf("%d\n", tsum);
}
}
return 0;
}