Cod sursa(job #3120579)

Utilizator mihai.constantinConstantin Mihai mihai.constantin Data 7 aprilie 2023 16:42:12
Problema Subsir crescator maximal Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 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];

int arb[4 * 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;

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

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

    for (i = 1; i <= n; i++) {
        maxim = 0;
        // pred[i] = -1;
        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); 

        
    }

    // for (i = 1; i <= 2 * n - 1; i++) {
    //     cout << arb[i] << " ";
    // }
    // cout << "\n";

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

    return 0;
}