Skip to content

Commit

Permalink
improves LIS implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
iagorrr committed May 19, 2024
1 parent 13c248b commit b0cb317
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
52 changes: 39 additions & 13 deletions algorithms/dynamic-programming/longest-increasing-subsequence.cpp
Original file line number Diff line number Diff line change
@@ -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<typename T>
pair<int, vector<int>> lis(const vector<T> &xs) {
int n = xs.size();

auto ans = 0;
vector<T> dp(n+1, numeric_limits<T>::max());
dp[0] = numeric_limits<T>::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<int> 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<typename T>
vector<int> get_idx(vector<T> xs) {
auto [sz1, psx1] = lis(xs);

reverse(xs.begin(), xs.end());
for (auto &xi : xs) xi = -xi;

auto [sz2, psx2] = lis(xs);

vector<int> 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;
}
Original file line number Diff line number Diff line change
@@ -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})$

0 comments on commit b0cb317

Please sign in to comment.