Cod sursa(job #1968177)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 17 aprilie 2017 15:32:13
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <bits/stdc++.h>

#define last_bit(x) (x&(-x))

using namespace std;

const int nmax = 1e5 + 10;
const int inf = 2e9 + 10;

const int bdim = 8;

int n, a[nmax];
int best[nmax], fen[nmax];
vector < int > values;

void input() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
}

void rsort(int p) {
    int cnt[1<<bdim]; memset(cnt, 0, sizeof(cnt));

    int mask = (1 << bdim) - 1;
    for (auto &x: values)
        cnt[(x>>p)&mask]++;

    for (int i = 1; i <= mask; ++i)
        cnt[i] += cnt[i-1];

    vector < int > aux(values.size());
    for (auto &x: values)
        aux[--cnt[(x>>p)&mask]] = x;
    swap(values, aux);
}

void _sort() {
    for (int i = 0; i < 32; i += bdim)
        rsort(i);
}

void run_norm() {
    for (int i = 1; i <= n; ++i)
        values.push_back(a[i]);

    _sort();

    sort(values.begin(), values.end());
    auto it = unique(values.begin(), values.end());
    values.resize(distance(values.begin(), it));

    for (int i = 1; i <= n; ++i)
        a[i] = lower_bound(values.begin(), values.end(), a[i]) - values.begin() + 1;
}

void update(int pos, int val) {
    for ( ; pos <= values.size(); pos += last_bit(pos))
        fen[pos] = max(fen[pos], val);
}

int query(int pos) {
    int res = 0;
    for ( ; pos; pos -= last_bit(pos))
        res = max(res, fen[pos]);
    return res;
}

void compute_scmax() {
    run_norm();

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

void output() {
    int ans = 0;
    for (int i = 1; i <= n; ++i)
        ans = max(ans, best[i]);

    printf("%d\n", ans);

    vector < int > all; all.push_back(inf);
    for (int i = n; i && ans; --i)
        if (best[i] == ans && a[i] < all.back())
            all.push_back(values[a[i]-1]), ans--;

    reverse(all.begin(), all.end()); all.pop_back();

    for (auto &it: all) printf("%d ", it);
    printf("\n");
}

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

    input();
    compute_scmax();
    output();

    return 0;
}