Cod sursa(job #2788372)

Utilizator StasBrega Stanislav Stas Data 25 octombrie 2021 16:43:47
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.18 kb
#include <bits/stdc++.h>

#define ll long long
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vector<int>>
#define vf vector<long double>
#define vvf vector<vector<long double>>
#define f first
#define s second
#define pb push_back
#define lsh(i) (1 << (i))
#define fi(i, n) for(int i = 0; (i) < (n); ++(i))
#define fe(x, a) for(auto &x: (a))
#define all(a) (a).begin(), (a).end()

using namespace std;

int val, poz, ls;
vpii segtree;

void update(int c, int l, int r) {
    if(l == r) {
        segtree[c] = {val, ls};
        return;
    }
    int m = (l + r) / 2;
    if(poz <= m)
        update(2 * c + 1, l, m);
    else
        update(2 * c + 2, m + 1, r);
    segtree[c] = segtree[2*c+1];
    if(segtree[2*c+2].f > segtree[c].f)
        segtree[c] = segtree[2*c+2];

}
pii query(int c, int l, int r) {
    if(l >= poz)
        return {0, -1};
    if(r < poz)
        return segtree[c];
    int m = (l + r) / 2;
    pii cur_ans = query(2*c+1,l,m), pos_ans = query(2*c+2,m+1,r);
    if(pos_ans.f > cur_ans.f)
        cur_ans = pos_ans;
    return cur_ans;
}

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

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

    int n; cin >> n;
    vpii a(n);

    fi(i, n) {
        int x;
        cin >>x;
        a[i] = {x, i};
    }

    sort(all(a));

    map<int, int> mp, mp_r;
    int k = 0;

    for(auto &[x, poz]: a)
        if(mp.count(x))
            x = mp[x];
        else
            mp_r[k] = x,
            mp[x] = k++,
            x = mp[x];

    sort(all(a), [](pii x, pii y){return x.second < y.second;});

    segtree.resize(4 * n + 77, {0, -1});
    vi v(n);

    for(auto &[x, p]: a) {
        poz = x;
        auto[val_v, last] = query(0, 0, n - 1);
        val = val_v + 1;
        v[p] = last;
        ls = p;
        update(0, 0, n - 1);
    }

    cout << segtree[0].f<< '\n';

    int p = segtree[0].s;
    vi ans;

    while(p!=-1) {
        ans.pb(mp_r[a[p].f] );
        p = v[p];
    }

    reverse(all(ans));
    fe(x, ans)
        cout << x << ' ';

    return 0;

}