Cod sursa(job #2809756)

Utilizator Mihai_BarbuMihai Barbu Mihai_Barbu Data 27 noiembrie 2021 15:54:02
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>

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

int findPos(std::vector<int>& v, int pos, std::vector<int>& dp, int curr) {
    int l = 0;
    int r = curr - 1;

    int m;
    while (l <= r) {
        m = l + ((r - l) >> 1);

        if (v[pos] == v[dp[m]]) {
            return m;
        }

        if (v[pos] > v[dp[m]]) {
            l = m + 1;
        } else {
            r = m - 1;
        }
    }

    return l;
}

int main() {
    int N;
    int i;

    fin >> N;

    std::vector<int> v(N);

    for (i = 0; i < N; ++i) {
        fin >> v[i];
    }

    /**
     * dp[i] = pos
     * v[pos] = min. elem s.t.
     *          there is a strictly increasing
     *          subsequence of length (i + 1)
     *          ending with v[pos]
     */
    std::vector<int> dp(N);

    /**
     * prev[i] = index of the previous elem
     *           leading to the increasing subsequence
     *           ending with v[i] 
     */
    std::vector<int> prev(N);

    dp[0] = 0;
    prev[0] = -1;

    int len = 1;

    int pos;
    for (i = 1; i < N; ++i) {
        prev[i] = -1;
        pos = findPos(v, i, dp, len);

        dp[pos] = i;
        if (pos == len) {
            // a greater subsequnce was found
            ++len;
        }

        if (pos) {
            prev[i] = dp[pos - 1];
        }
    }

    fout << len << "\n";

    std::vector<int> res(len);
    int curr = dp[len - 1];

    i = len - 1;
    while (curr != -1) {
        res[i] = v[curr];
        --i;

        curr = prev[curr];
    }

    for (i = 0; i < len; ++i) {
        fout << res[i] << " ";
    }
    fout << "\n";

    return 0;
}