Cod sursa(job #2664567)

Utilizator YetoAdrian Tonica Yeto Data 28 octombrie 2020 20:22:50
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
using namespace std;
int n, i, maxim = -1, k, poz;
int v[100001], a[100001], sol[100001], pre[100001];
ifstream fin ("scmax.in");
ofstream fout ("scmax.out");

/*  
    cauta binar cel mai mare element mai mic decat v[i]. 
    v[i] va fi inserat in a dupa el. v[i] e incadrat in a 
    astfel incat ordinea elementelor v[a[i]] e crescatoare.
*/
int cautbinar (int k, int x)
{
    int st = 1, dr = k;
    while (st <= dr) {
        int mid = (st + dr) / 2;
        if (v[a[mid]] >= x) {
            dr = mid - 1;
        } else {
            st = mid + 1;
        }
    }

    return st;
}

int main() {
    fin >> n;
    for (i = 1; i <= n; i++) {
        fin >> v[i];
    }

    // k este numarul curent de elemente din a
    // a retine, in ordine, indicii elementelor ce formeaza scmax
    /*
        pt exemplul :
        in: 5                   |    out: 3  
            24 12 15 15 19      |         12 15 19
        avem a[1] = 2, a[2] = 4, a[3] = 5

        pre[i] = pozitia valorii ce preceda elementul i in scmax ce se termina
                 pe pozitia i
    */
    k = 1; a[k] = 1;
    for (i = 2; i <= n; i++) {
        int p = cautbinar(k, v[i]);
        a[p] = i;
        // k ramane neschimbat daca niciun element nu este adaugat in e (p neschimbat)
        // nu conteaza daca sirul din a se strica (nu e valid), reconstituirea se face 
        // cu ajutorul lui pre, pornind de la elementul de pe pozitia poz (cel in care)
        // se termina scmax.
        k = max(k , p);
        // pentru reconstituire
        pre[i] = a[p - 1];
        if (p > maxim) {
            maxim = p;
            poz = i;
        }
    }

    fout << maxim << "\n";
    while (k > 0) {
        sol[k] = v[poz];
        k--;
        poz = pre[poz];
    }

    for (i = 1; i <= maxim; i++) {
        fout << sol[i] << " ";
    }

    return 0;
}