Library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub ebi-fly13/Library

:heavy_check_mark: LIS
(math/longest_increasing_subsequence.hpp)

説明

与えられた数列に対して、最長増加部分列となる添え字の列構築する。narrowlytrue のとき狭義単調増加、 false のとき広義単調増加の場合に対して構築する。$O(N\log N)$

Verified with

Code

#pragma once

#include <algorithm>
#include <limits>
#include <vector>

namespace ebi {

template <class T> std::vector<T> LIS(const std::vector<T> &a, bool narrowly) {
    std::vector<T> ret = {std::numeric_limits<T>::max()};
    std::vector<int> used;
    used.reserve(a.size());
    for (auto x : a) {
        auto itr = narrowly ? std::lower_bound(ret.begin(), ret.end(), x)
                            : std::upper_bound(ret.begin(), ret.end(), x);
        used.emplace_back(itr - ret.begin());
        if (itr == ret.end())
            ret.emplace_back(x);
        else
            *itr = x;
    }
    int len = ret.size();
    int idx = len - 1;
    T now = std::numeric_limits<T>::max();
    std::vector<int> lis(len);
    for (int i = int(a.size()) - 1; i >= 0; i--) {
        if (used[i] == idx && a[i] + int(narrowly) <= now) {
            now = a[i];
            lis[idx--] = i;
        }
    }
    return lis;
}

}  // namespace ebi
#line 2 "math/longest_increasing_subsequence.hpp"

#include <algorithm>
#include <limits>
#include <vector>

namespace ebi {

template <class T> std::vector<T> LIS(const std::vector<T> &a, bool narrowly) {
    std::vector<T> ret = {std::numeric_limits<T>::max()};
    std::vector<int> used;
    used.reserve(a.size());
    for (auto x : a) {
        auto itr = narrowly ? std::lower_bound(ret.begin(), ret.end(), x)
                            : std::upper_bound(ret.begin(), ret.end(), x);
        used.emplace_back(itr - ret.begin());
        if (itr == ret.end())
            ret.emplace_back(x);
        else
            *itr = x;
    }
    int len = ret.size();
    int idx = len - 1;
    T now = std::numeric_limits<T>::max();
    std::vector<int> lis(len);
    for (int i = int(a.size()) - 1; i >= 0; i--) {
        if (used[i] == idx && a[i] + int(narrowly) <= now) {
            now = a[i];
            lis[idx--] = i;
        }
    }
    return lis;
}

}  // namespace ebi
Back to top page