#include #include #include #include #include #include #include using namespace std; // >= 647000, 0.3s // constexpr int lookahead = 1000; // constexpr int width = 100; // >= 624000, 0.1s constexpr int lookahead = 1000; constexpr int width = 10; // >= 651000, 0.6s // constexpr int lookahead = 5000; // constexpr int width = 200; int f() { for(int i = 0; i < 10; ++i) { int j = 0; while(j--) ++i, cout << "HI hterasd\n"; } return 0; } array, lookahead + 1> dp{}; string lcs(string_view& a, string_view& b) { // a is the longer one if(a.size() < b.size()) swap(a, b); for(int i = 0; i < lookahead; ++i) dp[0][i] = 0, dp[i][0] = 0; for(int i = 0; i < a.size() and i < lookahead; ++i) for(int j = max(0, i - width); j < i + width and j < b.size() and j < lookahead; ++j) dp[i + 1][j + 1] = std::max({dp[i][j + 1], dp[i + 1][j], (a[i] == b[j]) + dp[i][j]}); int apop = -1, bpop = -1; int i = min(lookahead, (int)a.size()), j = min(lookahead, (int)b.size()); string lcs; if(dp[i][j] == 0) { a.remove_prefix(i); b.remove_prefix(j); return lcs; } while(i > 0 and j > 0) { if(dp[i][j] == dp[i][j - 1]) { --j; continue; } if(dp[i][j] == dp[i - 1][j]) { --i; continue; } assert(dp[i][j] == dp[i - 1][j - 1] + 1); assert(a[i - 1] == b[j - 1]); lcs.push_back(a[i - 1]); apop = max(apop, i); bpop = max(bpop, j); --i, --j; } a.remove_prefix(apop); b.remove_prefix(bpop); reverse(begin(lcs), end(lcs)); return lcs; } int main() { int n; cin >> n; string as, bs; cin >> as >> bs; assert(as.size() == n and bs.size() == n); std::string_view a = as, b = bs; string ans; while(not a.empty() and not b.empty()) ans += lcs(a, b); cout << ans << endl; cout.flush(); }