This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/dp/longest_increasing_sequence.hpp"
vector<int> longest_increasing_sequence(vector<T> a)
長さ $n$ の配列 a
の最長増加部分列 lcp
を計算します.
lcp[i]
は,最長増加部分列の $i$ 番目の要素の添え字を表します.
計算量
#pragma once
#include "../template/template.hpp"
template <typename T>
vector<int> longest_increasing_sequence(const vector<T>& a) {
const int n = a.size();
vector<pair<T, int>> dp;
vector<int> p(n, -1);
for(int i = 0; i < n; ++i) {
auto it = lower_bound(begin(dp), end(dp), make_pair(a[i], -i));
if(it != begin(dp)) p[i] = -prev(it)->second;
if(it == end(dp)) {
dp.emplace_back(a[i], -i);
} else {
*it = make_pair(a[i], -i);
}
}
vector<int> res;
for(int i = -dp.back().second; i != -1; i = p[i]) res.push_back(i);
reverse(begin(res), end(res));
return res;
}
#line 2 "src/template/template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<long long, long long>;
#define rep(i, a, b) for(long long i = (a); i < (b); ++i)
#define rrep(i, a, b) for(long long i = (a); i >= (b); --i)
constexpr long long inf = 4e18;
struct SetupIO {
SetupIO() {
ios::sync_with_stdio(0);
cin.tie(0);
cout << fixed << setprecision(30);
}
} setup_io;
#line 3 "src/dp/longest_increasing_sequence.hpp"
template <typename T>
vector<int> longest_increasing_sequence(const vector<T>& a) {
const int n = a.size();
vector<pair<T, int>> dp;
vector<int> p(n, -1);
for(int i = 0; i < n; ++i) {
auto it = lower_bound(begin(dp), end(dp), make_pair(a[i], -i));
if(it != begin(dp)) p[i] = -prev(it)->second;
if(it == end(dp)) {
dp.emplace_back(a[i], -i);
} else {
*it = make_pair(a[i], -i);
}
}
vector<int> res;
for(int i = -dp.back().second; i != -1; i = p[i]) res.push_back(i);
reverse(begin(res), end(res));
return res;
}