Cod sursa(job #3166106)

Utilizator misu_LIXulescu Vasile misu_L Data 7 noiembrie 2023 18:37:25
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
/// cu arbori de intervale
#include <fstream>
#include <algorithm>
#include <stack>

using namespace std;

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

pair <int, int> v[100002], cp[100002];
int n, tree[400010];
stack <int> rez;

int query(int node, int st, int dr, int left, int rigt) {
    if (left <= st and dr <= rigt) {
        return tree[node];
    }

    int mij = (st + dr) / 2, rez1 = 0, rez2 = 0;
    if (left <= mij) {
        rez1 = query(2*node, st, mij, left, rigt);
    }
    if (mij < rigt) {
        rez2 = query(2*node+1, mij+1, dr, left, rigt);
    }
    return max(rez1, rez2);
}

void update(int node, int st, int dr, int pos, int val) {
    if (st == dr and st == pos) {
        tree[node] = val;
        return ;
    }

    int mij = (st + dr)/2;
    if (pos <= mij) {
        update(2*node, st, mij, pos, val);
    } else {
        update(2*node+1, mij+1, dr, pos, val);
    }
    tree[node] = max(tree[2*node], tree[2*node+1]);
}

bool cmp(pair<int, int> a, pair<int, int> b) {
    if (a.first == b.first)
        return a.second > b.second;
    return a.first < b.first;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> v[i].first;
        cp[i].first = v[i].first;
        v[i].second = i;
    }

    sort(v+1, v+n+1, cmp); /// sortam dupa valoare, retinand pozitia

    int maxim = 0, pos;
    for (int i = 1; i <= n; i++) {
        int nr = query(1, 1, n, 1, v[i].second);
        update(1, 1, n, v[i].second, nr+1);
        cp[v[i].second].second = nr+1;
        if (nr+1 >= maxim) {
            maxim = nr+1;
            pos = v[i].second;
        }
    }

    cout << tree[1] << '\n';
    while (maxim and pos) {
        if (cp[pos].second == maxim) {
            rez.push(cp[pos].first);
            maxim--; pos--;
        }
        else
            pos--;
    }

     while (!rez.empty()) {
        cout << rez.top() << " ";
        rez.pop();
    }

    return 0;
}