Cod sursa(job #3140975)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 11 iulie 2023 15:38:11
Problema Subsir crescator maximal Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <fstream>
#include <algorithm>
using namespace std;

const int NMAX = 100000;

int query(int value, int aib[]);
void update(int value, int len, int aib[]);

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

    int v[NMAX], vs[NMAX];

    int n;
    fin >> n;

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

    sort(vs, vs+n);
    for (int i = 0; i < n; ++i)
        v[i] = lower_bound(vs, vs+n, v[i]) - vs;

    int aib[NMAX+1];
    for (int i = 0; i <= NMAX; ++i)
        aib[i] = 0;

    int sol = 0;
    int isol = -1;

    for (int i = 0; i < n; ++i) {
        int prev = query(v[i]-1, aib);
        int curr = prev + 1;
        update(v[i], curr, aib);

        if (curr > sol) {
            sol = curr;
            isol = i;
        }
    }

    fout << sol << '\n';

    int elements[NMAX];
    elements[sol-1] = v[isol];
    int c = sol-1;

    while (c > 0) {
        while (v[isol] >= elements[c] || query(v[isol], aib) != c)
            --isol;
        elements[--c] = v[isol];
    }

    for (int i = 0; i < sol; ++i)
        fout << vs[elements[i]] << ' ';
    fout << '\n';

    return 0;
}

int query(int value, int aib[])
{
    ++value;
    int sol = 0;

    while (value > 0) {
        sol = max(sol, aib[value]);
        value -= (value & -value);
    }

    return sol;
}

void update(int value, int len, int aib[])
{
    ++value;
    while (value <= NMAX) {
        aib[value] = max(aib[value], len);
        value += (value & -value);
    }
}