bzoj4259
fft
搞一个生成函数
对于每位A(j)=Σi=1->m (a[i]-b[i+j])^2*a[i]*b[i+j]
如果A(j)=0说明这位匹配
如果这位是*那么a[i]=0否则等于字母-'a'+1,b也是这样构造
然后我们翻转a串就可以加速了
#include<bits/stdc++.h> using namespace std; #define pi acos(-1) const int N = (1 << 20) + 5; int n = 1, n1, n2, k; char s1[N], s2[N]; int t[N], ans[N]; struct data { double a, b; data() { a = 0; b = 0; } data(double _, double __) : a(_), b(__) {} data friend operator + (const data &a, const data &b) { return data(a.a + b.a, a.b + b.b); } data friend operator - (const data &a, const data &b) { return data(a.a - b.a, a.b - b.b); } data friend operator * (const data &a, const data &b) { return data(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a); } } a0[N], b0[N], a1[N], b1[N], a2[N], b2[N]; void fft(data *a, int f) { for(int i = 0; i < n; ++i) { int t = 0; for(int j = 0; j < k; ++j) if(i >> j & 1) t |= 1 << (k - j - 1); if(i < t) swap(a[i], a[t]); } for(int l = 2; l <= n; l <<= 1) { int m = l >> 1; data w = data(cos(pi / m), f * sin(pi / m)); for(int i = 0; i < n; i += l) { data t = data(1, 0); for(int k = 0; k < m; ++k, t = t * w) { data x = a[i + k], y = t * a[i + k + m]; a[i + k] = x + y; a[i + k + m] = x - y; } } } } int main() { scanf("%d%d%s%s", &n1, &n2, s1, s2); reverse(s1, s1 + n1); --n1; --n2; for(int i = 0; i <= n1; ++i) if(s1[i] != '*') { double x = s1[i] - 'a' + 1; a0[i] = data(x, 0); a1[i] = data(x * x, 0); a2[i] = data(x * x * x, 0); } for(int i = 0; i <= n2; ++i) if(s2[i] != '*') { double x = s2[i] - 'a' + 1; b0[i] = data(x, 0); b1[i] = data(-2 * x * x, 0); b2[i] = data(x * x * x, 0); } while(n <= n1 + n2) n <<= 1, ++k; fft(a0, 1); fft(a1, 1); fft(a2, 1); fft(b0, 1); fft(b1, 1); fft(b2, 1); for(int i = 0; i < n; ++i) a2[i] = a2[i] * b0[i], a1[i] = a1[i] * b1[i], a0[i] = a0[i] * b2[i], a2[i] = a2[i] + a1[i] + a0[i]; fft(a2, -1); for(int i = 0; i < n; ++i) t[i] = (int)(a2[i].a / n + 0.1); for(int i = 0; i <= n2 - n1; ++i) if(t[i + n1] == 0) ans[++ans[0]] = i + 1; printf("%d\n", ans[0]); for(int i = 1; i < ans[0]; ++i) printf("%d ", ans[i]); printf("%d\n", ans[ans[0]]); return 0; }