Cod sursa(job #3322065)

Utilizator apoputoaievladVlad Cristian Apoputoaie apoputoaievlad Data 12 noiembrie 2025 15:56:56
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <fstream>
#include <vector>
#include <set>
#include <unordered_map>
#include <algorithm>

using namespace std;
ifstream cin("scmax.in");
ofstream cout("scmax.out");

class SegTree {
    vector<int> aint;
    int cap;

    void update(int nod, int st, int dr, int poz, int val) {
        if (st == dr) {
            aint[nod] = val;
            return;
        }

        int m = (st + dr) / 2;

        if (poz <= m) {
            update(2 * nod, st, m, poz, val);
        } else {
            update(2 * nod + 1, m + 1, dr, poz, val);
        }

        aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
    }

    int query(int nod, int st, int dr, int qst, int qdr) {
        if (st >= qst && dr <= qdr) {
            return aint[nod];
        }

        int m = (st + dr) / 2;
        int ans = 0;

        if (qst <= m) {
            ans = query(2 * nod, st, m, qst, qdr);
        }

        if (m < qdr) {
            ans = max(ans, query(2 * nod + 1, m + 1, dr, qst, qdr));
        }

        return ans;
    }

public:
    SegTree(int n) {
        cap = n;
        aint.resize(4 * cap, 0);
    }

    void change(int poz, int val) {
        // cout << "change " << poz << ' ' << val << '\n';
        update(1, 1, cap, poz, val);
    }

    int get(int st, int dr) {
        // cout << "get " << st << ' ' << dr << '\n';
        return query(1, 1, cap, st, dr);
    }
};

int main() {
    int n;
    cin >> n;

    vector<int> a(n + 5), dp(n + 5);
    set<int> s;
    unordered_map<int, int> val;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        s.insert(a[i]);
    }

    int cnt = 0;
    for (auto i: s) {
        val[i] = ++cnt;
    }
    SegTree aint(cnt + 5);
    int ans = 0, valAns = 0;
    for (int i = 1; i <= n; i++) {
        if (val[a[i]] > 1) {
            dp[i] = aint.get(1, val[a[i]] - 1);
        }
        dp[i]++;

        // cout << i << ' ' << dp[i] << '\n';
        if (dp[i] > ans) {
            ans = dp[i];
            valAns = a[i];
        }

        aint.change(val[a[i]], dp[i]);
    }

    cout << ans << '\n';

    vector<int> sir;
    for (int i = n; i >= 1; i--) {
        if (dp[i] == ans && a[i] <= valAns) {
            ans--;
            valAns = a[i] - 1;
            sir.push_back(a[i]);
        }
    }

    reverse(sir.begin(), sir.end());
    for (auto i: sir) {
        cout << i << ' ';
    }
}