Cod sursa(job #3120587)

Utilizator mihai.constantinConstantin Mihai mihai.constantin Data 7 aprilie 2023 17:06:28
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

ifstream in("scmax.in");
ofstream out("scmax.out");

const int dim = 100005;

struct elem {
    int val;
    int pos;
} v[dim];

struct {
    int val;
    int lung;
} aux[dim];

int arb[4 * dim];
int sol[dim];

bool cmp(struct elem e1, struct elem e2) {
    if (e1.val == e2.val) {
        return e1.pos > e2.pos;
    }
    return e1.val < e2.val;
}

void query(int nod, int st, int dr, int a, int b, int &maxim) {
    if (a <= st && dr <= b) {
        maxim = max(maxim, arb[nod]);
        return;
    }
    int m = (st + dr) / 2;
    if (a <= m) {
        query(2 * nod, st, m, a, b, maxim);
    }
    if (b >= m + 1) {
        query(2 * nod + 1, m + 1, dr, a, b, maxim);
    }
}

void update(int nod, int st, int dr, int pos, int val) {
    if (st == dr) {
        arb[nod] = val;
        return;
    }

    int m = (st + dr) / 2;
    if (pos <= m) {
        update(2 * nod, st, m, pos, val);
    } else {
        update(2 * nod + 1, m + 1, dr, pos, val);
    }

    arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}

int main()
{
    int n, i, maxim, lung_pred, val_pred, k = 0;

    in >> n;
    for (i = 1; i <= n; i++) {
        in >> v[i].val;
        aux[i].val = v[i].val;
        v[i].pos = i;
    }

    sort(v + 1, v + n + 1, cmp);

    for (i = 1; i <= n; i++) {
        maxim = 0;
        query(1, 1, n, 1, v[i].pos, maxim); // determina maximul in intervalul [1, v[i].pos]

        update(1, 1, n, v[i].pos, maxim + 1); 

        aux[v[i].pos].lung = maxim + 1;

        // cout << "i: " << i << "; " << "pos: " << v[i].pos << "; max: " << maxim + 1 << "\n";
    }

    out << arb[1] << "\n";

    int lmax = aux[1].lung;
    int pos_lmax = 1;
    for (i = 2; i <= n; i++) {
        if (aux[i].lung > lmax) {
            lmax = aux[i].lung;
            pos_lmax = i;
        }
    }

    i = pos_lmax;
    lung_pred = lmax;
    val_pred = aux[i].val;
    sol[++k] = aux[i].val;
    i--;
    while (i >= 1) {
        if (aux[i].lung + 1 == lung_pred && aux[i].val < val_pred) {
            sol[++k] = aux[i].val;
            lung_pred = aux[i].lung;
            val_pred = aux[i].val;
        }
        i--;
    }
    for (i = k; i >= 1; i--) {
        out << sol[i] << " ";
    }
    out << "\n";

    return 0;
}