Cod sursa(job #617464)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 14 octombrie 2011 21:48:12
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.32 kb
#include <iostream>
#include <cstdio>
#include <algorithm>

#define NMax 100005
#define Infinity 2000000005

using namespace std;

int N, V[NMax], Index[NMax], Initial[NMax];
int AI[3*NMax], DP[NMax], F[NMax];

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

void Update (int K, int L, int R, int X, int Y)
{
    int Mid=(L+R)/2;
    if (L==R)
    {
        AI[K]=Y;
        return;
    }
    if (X<=Mid)
    {
        Update (2*K, L, Mid, X, Y);
    }
    else
    {
        Update (2*K+1, Mid+1, R, X, Y);
    }
    AI[K]=Max (AI[2*K], AI[2*K+1]);
}

int Query (int K, int L, int R, int QL, int QR)
{
    int Mid=(L+R)/2;
    if (QL<=L and R<=QR)
    {
        return AI[K];
    }
    int AnswerL=0, AnswerR=0;
    if (QL<=Mid)
    {
        AnswerL=Query (2*K, L, Mid, QL, QR);
    }
    if (QR>Mid)
    {
        AnswerR=Query (2*K+1, Mid+1, R, QL, QR);
    }
    return Max (AnswerL, AnswerR);
}

inline bool Compare (int i, int j)
{
    if (V[i]<V[j])
    {
        return true;
    }
    return false;
}

void Normalize ()
{
    sort (Index+1, Index+N+1, Compare);
    int CurrentV=0, X=-1;
    for (int i=1; i<=N; ++i)
    {
        if (V[Index[i]]!=X)
        {
            ++CurrentV;
        }
        X=V[Index[i]];
        V[Index[i]]=CurrentV;
    }
}

void LIS ()
{
    for (int i=1; i<=N; ++i)
    {
        if (V[i]==1)
        {
            DP[i]=1;
        }
        else
        {
            DP[i]=Query (1, 1, V[Index[N]], 1, V[i]-1)+1;
        }
        Update (1, 1, V[Index[N]], V[i], DP[i]);
    }
}

void Read ()
{
    freopen ("scmax.in", "r", stdin);
    scanf ("%d", &N);
    for (int i=1; i<=N; ++i)
    {
        scanf ("%d", &V[i]);
        Index[i]=i;
        Initial[i]=V[i];
    }
    Initial[N+1]=Infinity;
}

void Print (int L, int iStart)
{
    if (L==0)
    {
        return;
    }
    for (int i=iStart; i>0; --i)
    {
        if (DP[i]==L and Initial[i]<Initial[iStart+1])
        {
            Print (L-1, i-1);
            printf ("%d ", Initial[i]);
            return;
        }
    }
}

int main()
{
    Read ();
    Normalize ();
    LIS ();
    freopen ("scmax.out", "w", stdout);
    printf ("%d\n", AI[1]);
    Print (AI[1], N);
    return 0;
}