Cod sursa(job #3165818)

Utilizator divadddDavid Curca divaddd Data 6 noiembrie 2023 22:53:34
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <bits/stdc++.h>
#define pii pair<int, int>
using namespace std;
const int NMAX = 1e5+2;
int n,a[NMAX],dp[NMAX],t[NMAX];
pii v[NMAX];

ifstream fin("scmax.in");
ofstream fout("scmax.out");

struct Node {
    int idmax = 0, maxi = 0;
    Node operator + (Node const &aux) const {
        Node ans;
        ans.maxi = (maxi > aux.maxi ? maxi : aux.maxi);
        ans.idmax = (maxi >= aux.maxi ? idmax : aux.idmax);
        return ans;
    }
} aint[4*NMAX];

void build(int nod, int st, int dr){
    if(st == dr){
        aint[nod].idmax = st;
    }else{
        int mid = (st+dr)/2;
        build(2*nod, st, mid);
        build(2*nod+1, mid+1, dr);
        aint[nod] = aint[2*nod] + aint[2*nod+1];
    }
}

Node query(int nod, int st, int dr, int l, int r){
    if(l <= st && dr <= r){
        return aint[nod];
    }else{
        int mid = (st+dr)/2;
        Node ans;
        if(l <= mid){
            ans = ans+query(2*nod, st, mid, l, r);
        }
        if(r >= mid+1){
            ans = ans+query(2*nod+1, mid+1, dr, l, r);
        }
        return ans;
    }
}

void update(int nod, int st, int dr, int pos, int val){
    if(st == dr){
        aint[nod].maxi = val;
    }else{
        int mid = (st+dr)/2;
        if(pos <= mid){
            update(2*nod, st, mid, pos, val);
        }else{
            update(2*nod+1, mid+1, dr, pos, val);
        }
        aint[nod] = aint[2*nod] + aint[2*nod+1];
    }
}

int main()
{
    fin >> n;
    for(int i = 1; i <= n; i++){
        fin >> a[i];
    }
    build(1, 1, n);
    map<int, vector<int>> mp;
    for(int i = 1; i <= n; i++){
        mp[a[i]].push_back(i);
    }
    for(auto [sum, list]: mp){
        for(auto idx: list){
            t[idx] = query(1, 1, n, 1, idx).idmax;
            dp[idx] = 1+dp[t[idx]];
        }
        for(auto idx: list){
            update(1, 1, n, idx, dp[idx]);
        }
    }
    int maxi = 0, pos = 0;
    for(int i = 1; i <= n; i++){
        if(dp[i] > maxi){
            maxi = dp[i];
            pos = i;
        }
    }
    vector<int> ans;
    while(pos != 0){
        ans.push_back(pos);
        pos = t[pos];
    }
    fout << ans.size() << "\n";
    reverse(ans.begin(), ans.end());
    for(int it: ans){
        fout << a[it] << " ";
    }
    return 0;
}