Cod sursa(job #2409697)

Utilizator osiaccrCristian Osiac osiaccr Data 19 aprilie 2019 12:45:45
Problema Subsir crescator maximal Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <bits/stdc++.h>
#define DEF 100010

using namespace std;

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

int n, V[DEF], Dp[DEF], maxim, Pred[DEF], posMaxim, Ord[DEF], AiB[DEF];

vector < int > Sol;

set < int > S;

void update (int p, int x) {
    for (; p <= n; p += (p & -p)) {
        AiB[p] = max (AiB[p], x);
    }
}

int query (int p) {
    int maxim = 0;
    for (; p; p -= (p & -p)) {
        maxim = max (maxim, AiB[p]);
    }
    return maxim;
}

int find (int i) {
    int poz = Ord[V[i]] - 1;
    int rez = query (poz);
    return rez;
}

int main () {

    fin >> n;

    for (int i = 1; i <= n; ++ i) {
        fin >> V[i];
        S.insert (V[i]);
    }

    for (int i = 1; i <= n; ++ i) {
        auto it = S.find (V[i]);
        Ord[i] = distance (S.begin (), it) + 1;
    }

    Dp[1] = 1;
    for (int i = 2; i <= n; ++ i) {
        Dp[i] = 1;
        int best = query (Ord[i] - 1);
        Dp[i] += best;
        update (Ord[i], Dp[i]);
    }

    for (int i = 1; i <= n; ++ i) {
        if (maxim < Dp[i]) {
            maxim = Dp[i];
            posMaxim = i;
        }
    }

    fout << maxim << "\n";

    while (posMaxim) {
        Sol.push_back (V[posMaxim]);
        posMaxim = Pred[posMaxim];
    }

    for (int i = Sol.size () - 1; i >= 0; -- i) {
        fout << Sol[i] << " ";
    }

    return 0;
}