Cod sursa(job #2773449)

Utilizator radu.z5Zamfirescu Radu Ioan radu.z5 Data 6 septembrie 2021 23:08:34
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <fstream>

using namespace std;

void scmax(const int *a, const int n, ofstream &out) {
    // idx..[l] -> retine indexul elementului care termina ultimul scmax de
    // lungime l gasit
    int idxOfLastElementWihtinSubseqOfLength[n + 1];
    int prev[n];

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

    int maxLength = 1;
    int i;

    for (i = 1; i < n; i++) {
        int left = 1;
        int right = maxLength;
        int mid;

        // din subsirul crescator maxim de la pasul curent caut un element x
        // care ar permite lui a[i] sa se concateneze la subsirul care se
        // termina cu acel x;
        // daca acest x e chiar ultimul element din scmaxul de la pasul curent
        // inseamna ca obtin o noua solutie mai mare
        while (left <= right) {
            mid = ((right - left) >> 1) + left;

            if (a[idxOfLastElementWihtinSubseqOfLength[mid]] < a[i]) {
                // caut printre elemente mai mari de scmax[mid] din scmax
                left = mid + 1;
            } else {
                // caut printre elemente mai mici de scmax[mid] din scmax
                right = mid - 1;
            }
        }

        // daca dupa ce am terminat cautarea am iesit cu capatul dinspre stanga
        // la dreapta lui scmax[maxLength] inseamna ca a[i] e mai mare decat
        // toate elementele din scmaxul curent, in special decat ultimul, si
        // atunci pot extinde acest scmax cu a[i]
        if (left == maxLength + 1)
            ++maxLength;

        idxOfLastElementWihtinSubseqOfLength[left] = i;
        prev[i] = idxOfLastElementWihtinSubseqOfLength[left - 1];
    }

    int scmaxElements[maxLength];
    int j = maxLength - 1;
    i = idxOfLastElementWihtinSubseqOfLength[maxLength];

    while (i != -1) {
        scmaxElements[j--] = a[i];
        i = prev[i];
    }

    out << maxLength << '\n';
    for (int j = 0; j < maxLength; j++)
        out << scmaxElements[j] << ' ';
}

int main(void) {
    ifstream in("scmax.in");
    ofstream out("scmax.out");

    int n;
    in >> n;
    int a[n];

    for (int i = 0; i < n; i++)
        in >> a[i];
    
    scmax((const int *) a, n, out);

    in.close();
    out.close();
    return 0;
}