vector<int> Match(char *s1, char *s2) { vector<int> mat; int m = strlen(s1), n = strlen(s2); reverse(s1, s1 + m); static LL f[N], g[N], h[N], a[N], b[N]; int bit = 0; while ((1 << bit) < (n + m + 1)) bit ++; int tot = 1 << bit; for (int i = 0; i < tot; ++ i) h[i] = f[i] = g[i] = 0; for (int i = 0; i < m; ++ i) if (s1[i] == '*') f[i] = 0; else f[i] = s1[i] - 'a' + 1; for (int i = 0; i < n; ++ i) if (s2[i] == '*') g[i] = 0; else g[i] = s2[i] - 'a' + 1; //H(i - j) += F(i) * G(j) * (F(i) - G(j)) ^ 2 //H(i + j - m - 1) += F(i) * G1(m - j - 1) * (F(i) - G1(j)) ^ 2 /*for (int i = 0; i < tot; ++ i) f[i] = (qpow(f[i], 3) * g[i] % Mod - qpow(f[i] * g[i] % Mod, 2) * 2 % Mod + qpow(g[i], 3) * f[i] % Mod + Mod) % Mod;*/ for (int i = 0; i < tot; ++ i) a[i] = f[i] * f[i] * f[i]; for (int i = 0; i < tot; ++ i) b[i] = g[i]; NTT(a, bit, 1), NTT(b, bit, 1); for (int i = 0; i < tot; ++ i) h[i] = (h[i] + a[i] * b[i]) % Mod;
for (int i = 0; i < tot; ++ i) a[i] = f[i] * f[i]; for (int i = 0; i < tot; ++ i) b[i] = g[i] * g[i]; NTT(a, bit, 1), NTT(b, bit, 1); for (int i = 0; i < tot; ++ i) h[i] = (h[i] + (Mod - 2) * a[i] % Mod * b[i]) % Mod;
for (int i = 0; i < tot; ++ i) a[i] = f[i]; for (int i = 0; i < tot; ++ i) b[i] = g[i] * g[i] * g[i]; NTT(a, bit, 1), NTT(b, bit, 1); for (int i = 0; i < tot; ++ i) h[i] = (h[i] + a[i] * b[i]) % Mod;
NTT(h, bit, -1); // for (int i = m - 1; i < n; ++ i) cout << h[i] << ' '; // puts(""); for (int i = m - 1; i < n; ++ i) if (h[i] == 0) mat.push_back(i - m + 1); return mat; }