Cod sursa(job #2329591)

Utilizator igsifvevc avb igsi Data 26 ianuarie 2019 23:27:59
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.91 kb
#include <algorithm>
#include <fstream>
#include <iterator>
#include <vector>

int main()
{
    std::ifstream fin("scmax.in");
    std::ofstream fout("scmax.out");

    int n;
    fin >> n;

    // input vector
    std::vector<int> a;
    std::copy_n(std::istream_iterator<int>(fin), n, std::back_inserter(a));

    // subseq[i] is the index of the previous element in the longest subsequence ending at V[i] or -1.
    // we will use it to reconstruct the solution.
    std::vector<int> subseq(a.size());

    // tail[k] is the smallest element which is at the end (tail) of a subsequence of length k.
    // tail_position[k] is the index of tail[k] in the input vector.
    std::vector<int> tail, tail_position;

    tail.push_back(a[0]);
    tail_position.push_back(0);
    subseq[0] = -1;

    for (int i = 1; i < a.size(); ++i)
    {
        // Find the first element which is greater than a[i] or tail.end()
        auto it = std::lower_bound(tail.begin(), tail.end(), a[i]);
        int length = std::distance(tail.begin(), it) - 1;

        // If a[i] is the first element in its longest subsequence then we mark that it doesn't
        // have a previous element, otherwise we specify the previous element.
        subseq[i] = length == -1 ? -1 : tail_position[length];

        if (tail.size() == length + 1)
        {
            tail.push_back(a[i]);
            tail_position.push_back(i);
        }
        else if (tail[length + 1] > a[i])
        {
            tail[length + 1] = a[i];
            tail_position[length + 1] = i;
        }
    }

    // Print the length of the longest increasing subsequence.
    fout << tail.size() << std::endl;

    // Reconstruct a solution.
    std::vector<int> solution;
    for (int i = tail_position.back(); i != -1; i = subseq[i])
        solution.push_back(a[i]);

    std::reverse_copy(solution.begin(), solution.end(), std::ostream_iterator<int>(fout, " "));
    fout << std::endl;

    return 0;
}