From b0cb3172fb3a22d2c2f73329a7b0d77cdd6f799c Mon Sep 17 00:00:00 2001 From: iagorrr Date: Sun, 19 May 2024 13:03:09 -0300 Subject: [PATCH] improves LIS implementation --- .../longest-increasing-subsequence.cpp | 52 ++++++++++++++----- .../longest-increasing-subsequence.tex | 6 ++- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/algorithms/dynamic-programming/longest-increasing-subsequence.cpp b/algorithms/dynamic-programming/longest-increasing-subsequence.cpp index 937510e8..6a415726 100644 --- a/algorithms/dynamic-programming/longest-increasing-subsequence.cpp +++ b/algorithms/dynamic-programming/longest-increasing-subsequence.cpp @@ -1,18 +1,44 @@ -int LIS(const vi& as) { - const ll oo = 1e18; - int n = len(as); - vll lis(n + 1, oo); - lis[0] = -oo; +template +pair> lis(const vector &xs) { + int n = xs.size(); - auto ans = 0; + vector dp(n+1, numeric_limits::max()); + dp[0] = numeric_limits::min(); - for (int i = 0; i < n; ++i) { - auto it = lower_bound(all(lis), as[i]); - auto pos = (int)(it - lis.begin()); + int sz = 0; + vector psx(n); - ans = max(ans, pos); - lis[pos] = as[i]; - } + for (int i = 0; i < n; i++) { + auto it = lower_bound(dp.begin(), dp.end(), xs[i]); + auto pos = (int)(it - dp.begin()); + + sz = max(sz, pos); + + dp[pos] = xs[i]; + + psx[i] = pos; + } + + return {sz, psx}; +} + +template +vector get_idx(vector xs) { + auto [sz1, psx1] = lis(xs); + + reverse(xs.begin(), xs.end()); + for (auto &xi : xs) xi = -xi; + + auto [sz2, psx2] = lis(xs); + + vector ans; + int _n = xs.size(); + for (int i = 0; i < _n; i++) { + int l = psx1[i]; + int r = psx2[_n-i-1]; + if (l + r -1 == sz1) ans.push_back(i); + } + + return ans; - return ans; } diff --git a/algorithms/dynamic-programming/longest-increasing-subsequence.tex b/algorithms/dynamic-programming/longest-increasing-subsequence.tex index 4e949a64..2568bcc9 100644 --- a/algorithms/dynamic-programming/longest-increasing-subsequence.tex +++ b/algorithms/dynamic-programming/longest-increasing-subsequence.tex @@ -1,3 +1,7 @@ \subsection{Longest Increasing Subsequence (LIS)} -Finds the lenght of the longest subsequence in $$O(n \log{n})$$. + +Find the pair $(sz, psx)$ where $sz$ is the size of the longest subsequence and $psx$ is a vector where $psx_i$ tells the size of the longest increase subsequence that ends at position $i$. $get_idx$ just tells which indices could be in the longest increasing subsequence. + +Time: $O(n\log{n})$ +