1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| #include <bits/stdc++.h>
using u64 = uint64_t;
const int kMaxN = 2e3 + 5, kMod = 1e9 + 7;
int n, m; int f[kMaxN][2][kMaxN]; bool g[kMaxN][2][kMaxN]; u64 pw[kMaxN], hss[2][kMaxN], hst[kMaxN], rhst[kMaxN]; std::string s[2], t;
inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); } inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }
u64 gethash(u64 *hs, int l, int r) { return hs[r] - hs[l - 1] * pw[r - l + 1]; } u64 gethash_rev(int l, int r) { return gethash(rhst, m - r + 1, m - l + 1); }
void prework() { memset(hss, 0, sizeof(hss)); memset(hst, 0, sizeof(hst)); memset(rhst, 0, sizeof(rhst)); memset(pw, 0, sizeof(pw)); pw[0] = 1; for (int i = 1; i <= 2e3; ++i) pw[i] = 13331ull * pw[i - 1]; for (int o = 0; o < 2; ++o) { for (int i = 1; i <= n; ++i) hss[o][i] = 13331ull * hss[o][i - 1] + s[o][i]; } for (int i = 1; i <= m; ++i) { hst[i] = 13331ull * hst[i - 1] + t[i]; rhst[i] = 13331ull * rhst[i - 1] + t[m - i + 1]; } }
int solve(int o) { prework(); memset(f, 0, sizeof(f)), memset(g, 0, sizeof(g)); for (int i = 1; i <= n; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 1; k <= std::min(m / 2, n - i + 1); ++k) { g[i][j][2 * k] = (gethash(hss[j], i, i + k - 1) == gethash(hst, m - 2 * k + 1, m - k) && gethash(hss[j ^ 1], i, i + k - 1) == gethash_rev(m - k + 1, m)); } } } int ret = 0, cnt = 0; for (int i = 1; i <= n; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 1; k <= std::min(m / 2, i); ++k) { inc(f[i][j][2 * k], gethash(hss[j ^ 1], i - k + 1, i) == gethash_rev(1, k) && gethash(hss[j], i - k + 1, i) == gethash(hst, k + 1, 2 * k)); } if (o) dec(ret, f[i][j][m] + g[i][j][m]); for (int k = 1; k <= m; ++k) { if (s[j][i] != t[k]) continue; int sum = f[i][j][k]; if (k == 1) { inc(f[i][j][k], 1); } else { inc(f[i][j][k], f[i - 1][j][k - 1]); inc(sum, f[i - 1][j][k - 1]); if (s[j ^ 1][i] == t[k - 1] && k > 2) { inc(f[i][j][k], f[i - 1][j ^ 1][k - 2]); } } if (k == m) inc(ret, sum); else if (g[i + 1][j][m - k]) inc(ret, f[i][j][k]); } inc(ret, g[i][j][m]); } } return ret; }
void dickdreamer() { std::cin >> s[0] >> s[1] >> t; n = s[0].size(), m = t.size(); s[0] = " " + s[0], s[1] = " " + s[1], t = " " + t; if (m == 1) { int ans = 0; for (int i = 1; i <= n; ++i) ans += (s[0][i] == t[1]) + (s[1][i] == t[1]); return void(std::cout << ans << '\n'); } else if (m == 2) { int ans = 0; for (int i = 1; i <= n; ++i) { ans += (s[0][i] == t[1] && s[1][i] == t[2]) + (s[1][i] == t[1] && s[0][i] == t[2]); if (i < n) { ans += (s[0][i] == t[1] && s[0][i + 1] == t[2]); ans += (s[0][i + 1] == t[1] && s[0][i] == t[2]); ans += (s[1][i] == t[1] && s[1][i + 1] == t[2]); ans += (s[1][i + 1] == t[1] && s[1][i] == t[2]); } } return void(std::cout << ans << '\n'); } int ans = solve(0); std::reverse(t.begin() + 1, t.begin() + 1 + m); inc(ans, solve(1)); std::cout << ans << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (T--) dickdreamer(); return 0; }
|