Cod sursa(job #2391408)

Utilizator vladm98Munteanu Vlad vladm98 Data 28 martie 2019 20:23:53
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <bits/stdc++.h>

using namespace std;

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

const int MAXN = 100005;

int n;
int v[MAXN], dp[MAXN], last[MAXN], arb[4 * MAXN], denorm[MAXN];
vector<int> ans;
pair<int, int> aux[MAXN];
int maxval;

int query(int nod, int b, int st, int dr){
    if(0 <= st && dr <= b)
        return arb[nod];
    int mij = (st + dr) / 2, left = 0, right = 0;
    if(0 <= mij)
        left = query(2 * nod, b, st, mij);
    if(b > mij)
        right = query(2 * nod + 1, b, mij + 1, dr);
    if(dp[left] > dp[right])
        return left;
    return right;
}

void update(int nod, int st, int dr, int pos, int val){
    if(st == dr && st == pos){
        arb[nod] = val;
        return;
    }
    int mij = (st + dr) / 2;
    if(pos <= mij)
        update(2 * nod, st, mij, pos, val);
    else
        update(2 * nod + 1, mij + 1, dr, pos, val);
    if(dp[arb[2 * nod]] > dp[arb[2 * nod + 1]])
        arb[nod] = arb[2 * nod];
    else
        arb[nod] = arb[2 * nod + 1];
}

void read(){
    fin >> n;
    for(int i = 1; i <= n; ++i){
        fin >> v[i];
        aux[i].first = v[i];
        aux[i].second = i;
    }
    sort(aux + 1, aux + n + 1);
    int curentval = 1;
    for(int i = 1; i <= n; ++i){
        if(aux[i].first == aux[i + 1].first)
            aux[i].first = curentval;
        else{
            denorm[curentval] = aux[i].first;
            aux[i].first = curentval++;
        }
    }
    for(int i = 1; i <= n; ++i){
        v[aux[i].second] = aux[i].first;
        maxval = max(aux[i].first, maxval);
    }
}

int main()
{
    read();
    for(int i = 1; i <= n; ++i){
        int best = query(1, v[i] - 1, 0, maxval);
        dp[i] = dp[best] + 1;
        last[i] = best;
        update(1, 0, maxval, v[i], i);
    }
    int el = 0, start = 0;
    for(int i = 1; i <= n; ++i){
        if(dp[i] > el){
            el = dp[i];
            start = i;
        }
    }
    while(start != 0){
        ans.push_back(denorm[v[start]]);
        start = last[start];
    }
    reverse(ans.begin(), ans.end());
    fout << ans.size() << "\n";
    for(int i = 0; i < int(ans.size()); ++i)
        fout << ans[i] << " ";
    return 0;
}