Cod sursa(job #2147743)

Utilizator papinub2Papa Valentin papinub2 Data 28 februarie 2018 22:50:04
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.39 kb
#include <fstream>
#include <algorithm>
#include <vector>
#define mp make_pair

using namespace std;

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

const int Nmax = 100005;

vector<int> Aint(Nmax * 3);

struct salam
{
    int val;
    int poz;
}v[Nmax];

bool cmp1 (salam A, salam B)
{
    if (A.val == B.val)
        return A.poz < B.poz;
    return A.val < B.val;
}

bool cmp2 (salam A, salam B)
{
    return A.poz < B.poz;
}

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

    int mij = (st + dr) / 2;

    if (poz <= mij)
        Update(poz, val, nod * 2, st, mij);
    else
        Update(poz, val, nod * 2 + 1, mij + 1, dr);

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

void Query (int&ans, int Start, int Final, int nod, int st, int dr)
{
    if (st >= Start && dr <= Final)
    {
        ans = max(ans, Aint[nod]);
        return;
    }

    int mij = (st + dr) / 2;

    if (Start <= mij) Query(ans, Start, Final, nod * 2, st, mij);
    if (Final > mij) Query(ans, Start, Final, nod * 2 + 1, mij + 1, dr);
}

int main()
{
    int n, nr = 0, maxim = 0;
    in >> n;

    vector<int> dp(n + 1), rez(n + 1), sol(n + 1), copie(n + 1);

    for (int i = 1; i <= n; i++)
    {
        in >> v[i].val;
        v[i].poz = i;
        rez[i] = v[i].val;
    }

    sort (v + 1, v + n + 1, cmp1);

    for (int i = 1; i <= n; i++)
    {
        if (v[i].val != v[i - 1].val)
            copie[i] = ++nr;
        else
            copie[i] = nr;
    }

    for (int i = 1; i <= n; i++)
        v[i].val = copie[i];

    sort (v + 1, v + n + 1, cmp2);

    for (int i = 1; i <= n; i++)
    {
        if (v[i].val == 1)
        {
            dp[i] = 1;
            Update(v[i].val, dp[i], 1, 1, n);
        }

        else

        {
            int ans = 0;
            Query(ans, 1, v[i].val - 1, 1, 1, n);
            dp[i] = ans + 1;
            Update(v[i].val, dp[i], 1, 1, n);
        }
    }

    for (int i = 1; i <= n; i++)
        maxim = max (maxim, dp[i]);

    int w = maxim;

    for (int i = n; i >= 1; i--)
        if (dp[i] == w)
        {
            sol[w] = rez[i];
            w--;
        }

    out << maxim << '\n';
    for (int i = 1; i <= maxim; i++)
        out << sol[i] << ' ';
    return 0;
}