Cod sursa(job #2968468)

Utilizator cristiWTCristi Tanase cristiWT Data 21 ianuarie 2023 10:26:29
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.5 kb
#include <bits/stdc++.h>

#define ll long long

using namespace std;

struct max_aint {
    vector<pair<int, int>> _a;
//    first -> val | second -> index

    void resize(int _n) {
        _a = vector<pair<int, int>>(4 * _n);
    }

    void update(int nod, int l, int r, int pos, int val, int index) {
        if (l == r) {
            _a[nod] = {val, index};
            return;
        }

        int mid = (l + r) / 2;
        if (pos <= mid) update(2 * nod, l, mid, pos, val, index);
        else update(2 * nod + 1, mid + 1, r, pos, val, index);
        _a[nod] = max(_a[nod * 2], _a[nod * 2 + 1]);
    }

    pair<int, int> query(int nod, int l, int r, int x, int y) {
        if (r < x || l > y)
            return {INT_MIN, -1};
        if (x <= l && r <= y)
            return _a[nod];

        int mid = (l + r) / 2;
        pair<int, int> mx = {INT_MIN, INT_MIN};
        if (x <= mid) mx = max(mx, query(2 * nod, l, mid, x, y));
        if (y >= mid) mx = max(mx, query(2 * nod + 1, mid + 1, r, x, y));
        return mx;
    }
};

const int NMAX = 1e5 + 10;
int n, a[NMAX], dp[NMAX], last[NMAX], v[NMAX];

void normalize(int _n, int _a[]) {
    vector<pair<int, int>> _v;
    for (int i = 1; i <= _n; i++)
        _v.emplace_back(_a[i], i);
    sort(_v.begin(), _v.end());

    int _val = 2;
    for (int i = 0; i < _n; i++) {
        int aux = _v[i].first;
        _v[i].first = _val;
        if (i != _n - 1 && aux != _v[i + 1].first)
            _val++;
    }

    for (auto it: _v)
        _a[it.second] = it.first;
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);

    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i], v[i] = a[i];
    normalize(n, a);

    max_aint tree;
    tree.resize(n + 1);
    for (int i = 2; i <= n + 1; i++)
        tree.update(1, 1, n + 1, i, -1, i);
    for (int i = 1; i <= n; i++) {
        pair<int, int> crt = tree.query(1, 1, n + 1, 1, a[i] - 1);
        dp[i] = crt.first + 1;
        last[i] = crt.second;
        tree.update(1, 1, n + 1, a[i], dp[i], i);
    }

//    for (int i = 1; i <= n; i++)
//        cout << last[i] << ' ';
//    cout << '\n';

    int mx = INT_MIN, index;
    for (int i = 1; i <= n; i++)
        if (mx < dp[i]) mx = dp[i], index = i;
    cout << mx << '\n';
    vector<int> ans;
    while (index != 0)
        ans.push_back(v[index]), index = last[index];
    reverse(ans.begin(), ans.end());
    for (auto x: ans) cout << x << ' ';
}