Cod sursa(job #1690576)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 15 aprilie 2016 11:57:39
Problema Subsir crescator maximal Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 1e5 + 10;

int N;
int BIT[NMAX], Pos[NMAX], From[NMAX], V[NMAX], answer2[NMAX];

struct Element {
    int value, pos;
    bool operator<(const Element &rhs) const {
        return value == rhs.value ? pos > rhs.pos : value < rhs.value;
    }
} E[NMAX];

void Update(int pos, int value) {
    int cpos = pos;
    for ( ; pos <= N; pos += pos & -pos) {
        if (BIT[pos] < value) {
            BIT[pos] = value;
            Pos[pos] = cpos;
        }
    }
}

pair<int, int> Query(int pos) {
    int ret1 = 0, ret2 = 0;
    for ( ; pos; pos -= pos & -pos) {
        if (BIT[pos] > ret1) {
            ret1 = BIT[pos];
            ret2 = Pos[pos];
        }
    }
    return {ret1, ret2};
}

int main() {
    assert(freopen("scmax.in", "r", stdin));
    assert(freopen("scmax.out", "w", stdout));

    int i;

    scanf("%d", &N);
    for (i = 1; i <= N; ++i) {
        scanf("%d", &E[i].value);
        V[i] = E[i].value;
        E[i].pos = i;
    }
    sort(E + 1, E + N + 1);

    int answer = 0, ans_pos = 0;
    for (i = 1; i <= N; ++i) {
        int best = 0, pos = 0;
        tie(best, pos) = Query(E[i].pos);
        Update(E[i].pos, best + 1);
        if (best + 1 > answer) {
            answer = best + 1;
            ans_pos = E[i].pos;
        }
        From[E[i].pos] = pos;
    }
    cout << answer << '\n';

    int limit = answer;
    answer2[answer--] = ans_pos;
    while (From[ans_pos]) {
        answer2[answer--] = From[ans_pos];
        ans_pos = From[ans_pos];
    }

    for (i = 1; i <= limit; ++i)
        cout << V[i] << ' ';
    cout << '\n';

    return 0;
}