Cod sursa(job #3338300)

Utilizator David_RadavoiRadavoi David Alexandru David_Radavoi Data 2 februarie 2026 15:11:40
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

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

#define NMAX 100000

int v[NMAX + 1];
int best[NMAX + 1];
int tree[4 * NMAX + 1];
vector <int> fr;
vector <int> norm;

int getpos(int val){
    int st = 0, dr = norm.size() - 1, mij, sol = 0;
    while (st <= dr){
        mij = (st + dr) / 2;
        if (norm[mij] <= val){
            st = mij + 1;
            sol = mij;
        }
        else{
            dr = mij - 1;
        }
    }
    return sol + 1;
}

int query(int node, int st, int dr, int qr){
    if (dr <= qr) return tree[node];
    int mij = (st + dr) / 2;
    int rez = 0;
    if (st <= qr) {
        rez = max(rez, query(node * 2, st, mij, qr));
        if (mij < qr){
            rez = max(rez, query(node * 2 + 1, mij + 1, dr, qr));
        }
    }
    return rez;
}

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

int main()
{
    int N, poz;
    fin >> N;
    for (int i = 1; i <= N; i++){
        fin >> v[i];
        fr.push_back(v[i]);
    }
    sort(fr.begin(), fr.end());
    for (int i = 0; i < fr.size(); i++){
        if (i == 0 || fr[i] != fr[i - 1]){
            norm.push_back(fr[i]);
        }
    }
    int maxim = 0, pmax;
    for (int i = 1; i <= N; i++){
        best[i] = 1 + query(1, 1, N, getpos(v[i]) - 1);
        maxim = max(maxim, best[i]);
        if (maxim == best[i]){
            pmax = i;
        }
        update(1, 1, N, getpos(v[i]), best[i]);
    }
    fout << maxim << '\n';
    vector <int> rez;
    rez.push_back(pmax);
    int to_find = maxim - 1, last = pmax;
    for (int i = pmax - 1; i >= 1; i--){
        if (best[i] == to_find && v[i] < v[last]){
            last = i;
            rez.push_back(i);
            to_find--;
        }
    }
    for (int i = rez.size() - 1; i >= 0; i--){
        fout << v[rez[i]] << " ";
    }
    return 0;
}