Cod sursa(job #617467)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 14 octombrie 2011 21:51:50
Problema Secv Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

#define NMax 5005

using namespace std;

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

inline int Min (int a, int b)
{
    if (a<b)
    {
        return a;
    }
    return b;
}

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]);
    }
}

bool Valid ()
{
    vector <int> Sequence, Vector;
    int iMax=N;
    for (int i=N; i>0; --i)
    {
        if (DP[i]==AI[1])
        {
            iMax=i;
            break;
        }
    }
    for (int i=iMax; i>0; i=F[i])
    {
        Sequence.push_back (V[i]);
    }
    sort (Sequence.begin (), Sequence.end ());
    V[0]=-1;
    for (int i=1; i<=N; ++i)
    {
        if (V[Index[i]]!=V[Index[i-1]])
        {
            Vector.push_back (V[i]);
        }
    }
    sort (Vector.begin (), Vector.end ());
    for (unsigned i=0; i<Sequence.size (); ++i)
    {
        if (Sequence[i]!=Vector[i])
        {
            return false;
        }
    }
    return true;
}

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

void Print ()
{
    freopen ("secv.out", "w", stdout);
    printf ("%d\n", S);
}

int Length (int i)
{
    if (DP[i]==1)
    {
        return 1;
    }
    return Length (F[i])+i-F[i];
}

int main()
{
    Read ();
    Normalize ();
    LIS ();
    if (!Valid ())
    {
        S=-1;
        Print ();
        return 0;
    }
    for (int i=N; i>0; --i)
    {
        if (DP[i]==AI[1])
        {
            S=Min (S, Length (i));
        }
    }
    Print ();
    return 0;
}