|
| 1 | +#include <bits/stdc++.h> |
| 2 | +typedef long long ll; |
| 3 | +using namespace std; |
| 4 | + |
| 5 | +const ll P1 = 9973, P2 = 69420, M1 = 1e9 + 9, M2 = 998244353; |
| 6 | + |
| 7 | +ll inv(ll base, ll MOD) { |
| 8 | + ll ans = 1, expo = MOD - 2; |
| 9 | + while (expo) { |
| 10 | + if (expo & 1) ans = ans * base % MOD; |
| 11 | + expo >>= 1; |
| 12 | + base = base * base % MOD; |
| 13 | + } |
| 14 | + return ans; |
| 15 | +} |
| 16 | + |
| 17 | +string n, h; |
| 18 | + |
| 19 | +int main() { |
| 20 | + cin.tie(0)->sync_with_stdio(0); |
| 21 | + cin >> n >> h; |
| 22 | + if (n.size() > h.size()) return cout << 0, 0; |
| 23 | + |
| 24 | + set<pair<ll, ll>> good; |
| 25 | + ll n_hsh1 = 1, h_hsh1 = 1, n_hsh2 = 1, h_hsh2 = 1; |
| 26 | + ll poly1 = 0, poly2 = 0, p_pow1 = 1, p_pow2 = 1; |
| 27 | + for (int i = 0; i < n.size(); i++) { |
| 28 | + n_hsh1 = n_hsh1 * (P1 + n[i] - 'a') % M1; |
| 29 | + n_hsh2 = n_hsh2 * (P2 + n[i] - 'a') % M2; |
| 30 | + h_hsh1 = h_hsh1 * (P1 + h[i] - 'a') % M1; |
| 31 | + h_hsh2 = h_hsh2 * (P2 + h[i] - 'a') % M2; |
| 32 | + |
| 33 | + poly1 = (poly1 * P1 + (h[i] - 'a')) % M1; |
| 34 | + poly2 = (poly2 * P2 + (h[i] - 'a')) % M2; |
| 35 | + p_pow1 = p_pow1 * P1 % M1; |
| 36 | + p_pow2 = p_pow2 * P2 % M2; |
| 37 | + } |
| 38 | + if (n_hsh1 == h_hsh1 && n_hsh2 == h_hsh2) good.insert({poly1, poly2}); |
| 39 | + |
| 40 | + for (int i = n.size(); i < h.size(); i++) { |
| 41 | + h_hsh1 = h_hsh1 * inv(P1 + h[i - n.size()] - 'a', M1) % M1 * (P1 + h[i] - 'a') % M1; |
| 42 | + h_hsh2 = h_hsh2 * inv(P2 + h[i - n.size()] - 'a', M2) % M2 * (P2 + h[i] - 'a') % M2; |
| 43 | + |
| 44 | + poly1 = (poly1 * P1 - p_pow1 * (h[i - n.size()] - 'a') % M1 + (h[i] - 'a') + M1) % M1; |
| 45 | + poly2 = (poly2 * P2 - p_pow2 * (h[i - n.size()] - 'a') % M2 + (h[i] - 'a') + M2) % M2; |
| 46 | + |
| 47 | + if (n_hsh1 == h_hsh1 && n_hsh2 == h_hsh2) good.insert({poly1, poly2}); |
| 48 | + } |
| 49 | + |
| 50 | + cout << good.size() << '\n'; |
| 51 | + return 0; |
| 52 | +} |
0 commit comments