Cod sursa(job #3326091)

Utilizator CrisqButoi Cristian Crisq Data 27 noiembrie 2025 12:40:24
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.18 kb
#include <iostream>

// Include-urile standard C++ pentru manipularea fisierelor sunt necesare, chiar daca cerinta mentioneaza
// "doar include iostream", deoarece problema impune lucrul cu fisierele scmax.in si scmax.out.
// Fara aceste header-e, operatiunile pe fisiere nu sunt posibile in mod standard C++.
// Presupunand ca cerinta doreste minimizarea header-elor C++.

using namespace std;

// Functie ajutatoare pentru cautare binara
int cautareBinara(int d[], int len, int val) {
    int stanga = 0, dreapta = len - 1;
    int poz = len;
    while (stanga <= dreapta) {
        int mijloc = stanga + (dreapta - stanga) / 2;
        if (d[mijloc] >= val) {
            poz = mijloc;
            dreapta = mijloc - 1;
        } else {
            stanga = mijloc + 1;
        }
    }
    return poz;
}

void solve() {
    // Redirectioneaza intrarile/iesirile standard catre fisierele specificate
    // Aceasta este o metoda veche de a face IO in probleme de concurs,
    // evitand includerea <fstream>.
    FILE* fin = freopen("scmax.in", "r", stdin);
    FILE* fout = freopen("scmax.out", "w", stdout);

    if (fin == NULL || fout == NULL) {
        return; // Eroare la deschiderea fisierelor
    }

    int N;
    if (!(cin >> N)) return;

    // Alocare dinamica rudimentara, deoarece nu putem folosi vector standard
    int* a = new int[N];
    for (int i = 0; i < N; ++i) {
        cin >> a[i];
    }

    // d[i] va stoca cel mai mic element care termină un subșir crescător de lungime i+1
    int* d = new int[N];
    // p[i] stocheaza indicele elementului anterior din LIS
    int* p = new int[N];
    // idx[i] stocheaza indicele original din 'a' al elementului stocat in d[i]
    int* idx = new int[N];

    int len_d = 0; // Lungimea curenta a vectorului d (care este si lungimea LIS curent)

    for (int i = 0; i < N; ++i) {
        // Gaseste pozitia corecta pentru a[i] in vectorul d (folosind cautare binara)
        int pos = cautareBinara(d, len_d, a[i]);

        if (pos == len_d) {
            // Extindem LIS-ul
            d[len_d] = a[i];
            idx[len_d] = i;
            len_d++;
        } else {
            // Inlocuim elementul existent
            d[pos] = a[i];
            idx[pos] = i;
        }

        // Setam predecesorul pentru elementul curent
        if (pos > 0) {
            p[i] = idx[pos - 1];
        } else {
            p[i] = -1;
        }
    }

    int Lmax = len_d;
    cout << Lmax << "\n";

    // Reconstructia subșirului
    // Folosim o stiva (sau array temporar) pentru a inversa ordinea
    int* lis_temp = new int[Lmax];
    int current_idx = idx[len_d - 1];
    int count = 0;

    while (current_idx != -1) {
        lis_temp[count++] = a[current_idx];
        current_idx = p[current_idx];
    }

    // Afisare in ordine corecta (invers)
    for (int i = count - 1; i >= 0; --i) {
        cout << lis_temp[i] << (i == 0 ? "" : " ");
    }
    cout << "\n";

    // Eliberarea memoriei
    delete[] a;
    delete[] d;
    delete[] p;
    delete[] idx;
    delete[] lis_temp;

    fclose(fin);
    fclose(fout);
}

int main() {
    solve();
    return 0;
}