Cod sursa(job #1093219)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 27 ianuarie 2014 20:24:03
Problema Subsir crescator maximal Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.94 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 100000;

int v [N + 1];
int w [N + 1];
int x [N + 1];
int arb [N+1];
int rez [N];
int lMax [N];
int n, maxF;
bool f;

bool cmp(int x, int y)
{
    return v[x] < v[y];
}

int query (int x)
{
    int rez=0;

    while (x != 0)
    {
        if(arb [x] > rez)
            rez = arb [x];
        x -= x & (- x);
    }

    return rez + 1;
}

void update (int x, int val)
{
    while (x <= n)
    {
        if (arb [x] < val)
            arb [x] = val;
        x += x & (-x);
    }
}

void citire ()
{
    int i;

    scanf("%d", & n);

    for (i = 1; i <= n; i ++)
    {
        scanf ("%d", & v[i]);
        w [i] = i;
        if (v [i] < v [i + 1])
            f = true;
    }
}

void norm ()
{
    int i;

    sort (w + 1, w + n + 1, cmp);

    for (i = 1; i <= n; i ++)
        if(v [w [i]] == v [w [i - 1]] )
            x [w [i]] = x [w [i - 1]];

        else
            x [w [i]] = i;
}

void init ()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);
    citire ();
    norm ();
}

void rezolva ()
{
    int i, maxim = 0, l, sI;

    for (i = 1; i <= n; i ++)
    {
        l = query (x [i] - 1);
        lMax [i] = l;

        if (l > maxim)
        {
            maxim = l;
            sI = i;
        }

        update (x [i], l);
    }

    maxF = maxim;
    rez [maxF] = v [sI];
    maxim --;

    for (i = sI - 1; i > 0; i --)
        if (lMax [i] == maxim && v [i] < rez [maxim + 1])
        {
            rez [maxim]=v [i];
            maxim --;
        }
}

void afisare ()
{
    int i;

    printf ("%d\n", maxF);

    for (i = 1; i <= maxF; i ++)
        printf ("%d ", rez [i]);
}

int main()
{
    init ();
    if (! f)
        printf ("%d", v [1]);

    else
    {
        rezolva ();
        afisare ();
    }

    return 0;
}