#if defined(EMBE_DEBUG) && !defined(NDEBUG) #include "embe-debug.hpp" #else #define LOG_INDENT(...) do {} while (false) #define LOG(...) do {} while (false) #define DUMP(...) do {} while (false) #endif #include <algorithm> #include <array> #include <cassert> #include <iostream> #include <numeric> #include <string> #include <string_view> #include <vector> using namespace std; namespace { short ih[3003][3003]; short iv[3003][3003]; void calculate(string_view a_, string_view b_) { int na = a_.size(); int nb = b_.size(); auto a = a_.data(); auto b = b_.data(); for (int j = 0; j <= nb; ++j) { ih[0][j] = j; } for (int l = 0; l <= na; ++l) { iv[l][0] = 0; } for (int l = 1; l <= na; ++l) { auto* ivc = iv[l] + 1; auto* ihc = ih[l] + 1; auto* ihp = ih[l - 1]; short x = 0; auto bb = b; for (int j = 1; j <= nb; ++j) { auto y = ihp[j]; if (*a != *bb) { *ihc = max(x, y); x = *ivc = min(x, y); } else { *ihc = x; x = *ivc = y; } ++ihc; ++ivc; ++bb; } ++a; } } vector<int> solve(string_view a, string_view b, vector<array<int, 4>> const& queries) { vector<int> perm(queries.size()); vector<int> results(queries.size()); iota(perm.begin(), perm.end(), 0); sort(perm.begin(), perm.end(), [&](int x, int y) { return queries[x] < queries[y]; }); auto it = perm.begin(); while (it != perm.end()) { int i = queries[*it][0]; DUMP(i); auto it2 = it; auto Mj = queries[*it][1]; auto mk = queries[*it][2]; auto Ml = queries[*it][3]; while (it2 != perm.end() && queries[*it2][0] == i) { auto const& [_, j, k, l] = queries[*it2]; if (Mj < j) Mj = j; if (mk > k) mk = k; if (Ml < l) Ml = l; ++it2; } calculate(a.substr(i - 1, Mj - i + 1), b.substr(mk - 1, Ml - mk + 1)); int last_l = -1; int last_i = -1; int x = -1; int cur = -1; auto get = [&](int l_, int i_, int j_) { if (last_l != l_ || last_i != i_) { last_l = l_; last_i = i_; x = i_; cur = 0; } while (x < j_) { ++x; if (i_ >= ih[l_][x]) ++cur; } return cur; }; while (it != perm.end() && queries[*it][0] == i) { auto const& [_, j, k, l] = queries[*it]; results[*it] = get(j - i + 1, k - mk, l - mk + 1); ++it; } } return results; } } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m, q; cin >> n >> m >> q; string s, t; cin >> s >> t; vector<array<int, 4>> queries(q); for (auto& [i, j, k, l]: queries) { cin >> i >> j >> k >> l; } auto results = solve(s, t, queries); for (auto const& r: results) { cout << r << '\n'; } return 0; }
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 122 123 124 125 126 127 128 129 | #if defined(EMBE_DEBUG) && !defined(NDEBUG) #include "embe-debug.hpp" #else #define LOG_INDENT(...) do {} while (false) #define LOG(...) do {} while (false) #define DUMP(...) do {} while (false) #endif #include <algorithm> #include <array> #include <cassert> #include <iostream> #include <numeric> #include <string> #include <string_view> #include <vector> using namespace std; namespace { short ih[3003][3003]; short iv[3003][3003]; void calculate(string_view a_, string_view b_) { int na = a_.size(); int nb = b_.size(); auto a = a_.data(); auto b = b_.data(); for (int j = 0; j <= nb; ++j) { ih[0][j] = j; } for (int l = 0; l <= na; ++l) { iv[l][0] = 0; } for (int l = 1; l <= na; ++l) { auto* ivc = iv[l] + 1; auto* ihc = ih[l] + 1; auto* ihp = ih[l - 1]; short x = 0; auto bb = b; for (int j = 1; j <= nb; ++j) { auto y = ihp[j]; if (*a != *bb) { *ihc = max(x, y); x = *ivc = min(x, y); } else { *ihc = x; x = *ivc = y; } ++ihc; ++ivc; ++bb; } ++a; } } vector<int> solve(string_view a, string_view b, vector<array<int, 4>> const& queries) { vector<int> perm(queries.size()); vector<int> results(queries.size()); iota(perm.begin(), perm.end(), 0); sort(perm.begin(), perm.end(), [&](int x, int y) { return queries[x] < queries[y]; }); auto it = perm.begin(); while (it != perm.end()) { int i = queries[*it][0]; DUMP(i); auto it2 = it; auto Mj = queries[*it][1]; auto mk = queries[*it][2]; auto Ml = queries[*it][3]; while (it2 != perm.end() && queries[*it2][0] == i) { auto const& [_, j, k, l] = queries[*it2]; if (Mj < j) Mj = j; if (mk > k) mk = k; if (Ml < l) Ml = l; ++it2; } calculate(a.substr(i - 1, Mj - i + 1), b.substr(mk - 1, Ml - mk + 1)); int last_l = -1; int last_i = -1; int x = -1; int cur = -1; auto get = [&](int l_, int i_, int j_) { if (last_l != l_ || last_i != i_) { last_l = l_; last_i = i_; x = i_; cur = 0; } while (x < j_) { ++x; if (i_ >= ih[l_][x]) ++cur; } return cur; }; while (it != perm.end() && queries[*it][0] == i) { auto const& [_, j, k, l] = queries[*it]; results[*it] = get(j - i + 1, k - mk, l - mk + 1); ++it; } } return results; } } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m, q; cin >> n >> m >> q; string s, t; cin >> s >> t; vector<array<int, 4>> queries(q); for (auto& [i, j, k, l]: queries) { cin >> i >> j >> k >> l; } auto results = solve(s, t, queries); for (auto const& r: results) { cout << r << '\n'; } return 0; } |