Cod sursa(job #593266)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 1 iunie 2011 21:52:22
Problema Subsir crescator maximal Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include <iostream>
#include <fstream>

using namespace std;

ofstream fout ("scmax.out");

typedef struct
{
    long L;
    long V;
}
ArbInt;

ArbInt AI[200005];
long N, V[100005];

void Read ()
{
    ifstream fin ("scmax.in");
    long i;
    fin >> N;
    for (i=1; i<=N; i++)
    {
        fin >> V[i];
    }
    fin.close ();
}

void Type (long X)
{
    if (AI[X].L>0)
    {
        if ((AI[2*X].L==AI[X].L-1)&&(AI[2*X].V<AI[X].V))
        {
            Type (2*X);
        }
        if ((AI[2*X+1].L==AI[X].L-1)&&(AI[2*X+1].V<AI[X].V))
        {
            Type (2*X+1);
        }
        fout << AI[X].V << " ";
    }
}

long Max (long a, long b)
{
    if (a>b)
    {
        return a;
    }
    return b;
}

void Update (long Left, long Right, long X, long LX, long K, long VX)
{
    long Middle;
    Middle=(Left+Right)/2;
    if (Left==Right)
    {
        AI[K].L=LX;
        AI[K].V=VX;
        return;
    }
    if (X<=Middle)
    {
        Update (Left, Middle, X, LX, 2*K, VX);
    }
    else
    {
        Update (Middle+1, Right, X, LX, 2*K+1, VX);
    }
    if (AI[2*K].L>AI[2*K+1].L)
    {
        AI[K]=AI[2*K];
    }
    else
    {
        AI[K]=AI[2*K+1];
    }
}

long Query (long Left, long Right, long XLeft, long XRight, long K, long VX)
{
    long Middle;
    Middle=(Left+Right)/2;
    if ((Left==Right)&&(AI[K].V>=VX))
    {
        return 0;
    }
    if ((Left==XLeft)&&(Right==XRight))
    {
        if (AI[K].V<VX)
        {
            return AI[K].L;
        }
        else
        {
            return Max (Query (Left, Middle, XLeft, Middle, 2*K, VX), Query (Middle+1, Right, Middle+1, XRight, 2*K+1, VX));
        }
    }
    if (XRight<=Middle)
    {
        return Query (Left, Middle, XLeft, XRight, 2*K, VX);
    }
    if (XLeft>Middle)
    {
        return Query (Middle+1, Right, XLeft, XRight, 2*K+1, VX);
    }
    return Max (Query (Left, Middle, XLeft, Middle, 2*K, VX), Query (Middle+1, Right, Middle+1, XRight, 2*K+1, VX));
}

int main()
{
    long i, L;
    Read ();
    for (i=1; i<=N; i++)
    {
        L=Query (1, N, 1, i, 1, V[i]);
        Update (1, N, i, L+1, 1, V[i]);
    }
    fout << AI[1].L << "\n";
    Type (1);
    fout.close ();
    return 0;
}