Cod sursa(job #2273764)

Utilizator DavidLDavid Lauran DavidL Data 31 octombrie 2018 21:40:17
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fi("scmax.in");
ofstream fo("scmax.out");

const int NMAX = 100005;

int v[NMAX];
int w[NMAX];
int A[4 * NMAX];
int unde[4 * NMAX];
int dp[NMAX];
int ult[NMAX];
int old[NMAX];
int n;
unordered_map <int, int> cor;
int poz, val, st, dr, rez;
int dacolo;
int aiciaCumUnde;
vector <int> HAHAHA;

void refa()
{
    for (int i = 1; i <= n; i++)
        w[i] = v[i];
    sort(w + 1, w + n + 1);

    int cnt = 0;
    for (int i = 1; i <= n; i++)
        if (w[i] != w[i - 1])
            cor[w[i]] = ++cnt, old[cnt] = w[i];

    for (int i = 1; i <= n; i++)
        v[i] = cor[v[i]];
}

void query(int nod, int l, int r)
{
    if (st <= l && r <= dr)
    {
        if (A[nod] > rez)
        {
            rez = A[nod];
            aiciaCumUnde = unde[nod];
        }
        return;
    }

    int mij = (l + r) / 2;
    if (st <= mij)
        query(2 * nod, l, mij);
    if (dr > mij)
        query(2 * nod + 1, mij + 1, r);
}

void update(int nod, int l, int r)
{
    if (l == r)
    {
        A[nod] = val;
        unde[nod] = dacolo;
        return;
    }

    int mij = (l + r) / 2;

    if (poz <= mij)
        update(2 * nod, l, mij);
    else
        update(2 * nod + 1, mij + 1, r);

    if (A[2 * nod] > A[2 * nod + 1])
    {
        A[nod] = A[2 * nod];
        unde[nod] = unde[2 * nod];
    }
    else
    {
        A[nod] = A[2 * nod + 1];
        unde[nod] = unde[2 * nod + 1];
    }
}

int main()
{
    fi >> n;
    for (int i = 1; i <= n; i++)
        fi >> v[i];
    refa();

    /*for (int i = 1; i <= n; i++)
        fo << v[i] << " ";
    return 0;*/

    for (int i = 1; i <= n; i++)
    {
        st = 1, dr = v[i] - 1;

        if (dr == 0)
        {
            dp[i] = 1;
            ult[i] = 0;
        }
        else
        {
            rez = 0;
            query(1, 1, n);

            dp[i] = rez + 1;
            ult[i] = aiciaCumUnde;
        }
        poz = v[i];
        val = dp[i];
        dacolo = i;
        update(1, 1, n);
    }

    int maxim = 0, pmax = 0;
    for (int i = 1; i <= n; i++)
    {
        if (dp[i] > maxim)
            maxim = dp[i], pmax = i;
    }
    fo << maxim << "\n";
    //return 0;


    while (pmax)
    {
        ///fo << dp[pmax] << " ";
        HAHAHA.push_back(v[pmax]);
        if (dp[pmax] == 1)
            break;
        pmax = ult[pmax];
    }


    reverse(HAHAHA.begin(), HAHAHA.end());

    for (auto x: HAHAHA)
        fo << old[x] << " ";

    return 0;
}