C++ Library for Competitive Programming
#include "emthrm/dynamic_programming/longest_increasing_subsequence.hpp"
$i < j$ を満たす任意の $i, j$ に対して $A_i < A_j$ を満たす部分列 $A$ の内、最長のものである。
$O(N\log{N})$
名前 | 戻り値 | 備考 |
---|---|---|
template <bool IS_STRICT = true, typename T> std::vector<T> longest_increasing_subsequence(const std::vector<T>& a);
|
$A$ の最長増加部分列 |
IS_STRICT は広義単調増加であるかを表す。 |
https://judge.yosupo.jp/submission/99391
#ifndef EMTHRM_DYNAMIC_PROGRAMMING_LONGEST_INCREASING_SUBSEQUENCE_HPP_
#define EMTHRM_DYNAMIC_PROGRAMMING_LONGEST_INCREASING_SUBSEQUENCE_HPP_
#include <algorithm>
#include <iterator>
#include <limits>
#include <vector>
namespace emthrm {
template <bool IS_STRICT = true, typename T>
std::vector<T> longest_increasing_subsequence(const std::vector<T>& a) {
const T inf = std::numeric_limits<T>::max();
const int n = a.size();
std::vector<int> idx(n);
std::vector<T> tmp(n, inf);
for (int i = 0; i < n; ++i) {
idx[i] = std::distance(
tmp.begin(),
IS_STRICT ? std::lower_bound(tmp.begin(), tmp.end(), a[i]) :
std::upper_bound(tmp.begin(), tmp.end(), a[i]));
tmp[idx[i]] = a[i];
}
int res_size =
std::distance(tmp.begin(), std::lower_bound(tmp.begin(), tmp.end(), inf));
std::vector<T> res(res_size--);
for (int i = n - 1; res_size >= 0 && i >= 0; --i) {
if (idx[i] == res_size) res[res_size--] = a[i];
}
return res;
}
} // namespace emthrm
#endif // EMTHRM_DYNAMIC_PROGRAMMING_LONGEST_INCREASING_SUBSEQUENCE_HPP_
#line 1 "include/emthrm/dynamic_programming/longest_increasing_subsequence.hpp"
#include <algorithm>
#include <iterator>
#include <limits>
#include <vector>
namespace emthrm {
template <bool IS_STRICT = true, typename T>
std::vector<T> longest_increasing_subsequence(const std::vector<T>& a) {
const T inf = std::numeric_limits<T>::max();
const int n = a.size();
std::vector<int> idx(n);
std::vector<T> tmp(n, inf);
for (int i = 0; i < n; ++i) {
idx[i] = std::distance(
tmp.begin(),
IS_STRICT ? std::lower_bound(tmp.begin(), tmp.end(), a[i]) :
std::upper_bound(tmp.begin(), tmp.end(), a[i]));
tmp[idx[i]] = a[i];
}
int res_size =
std::distance(tmp.begin(), std::lower_bound(tmp.begin(), tmp.end(), inf));
std::vector<T> res(res_size--);
for (int i = n - 1; res_size >= 0 && i >= 0; --i) {
if (idx[i] == res_size) res[res_size--] = a[i];
}
return res;
}
} // namespace emthrm