Cod sursa(job #1366969)

Utilizator DorelBarbuBarbu Dorel DorelBarbu Data 1 martie 2015 15:14:20
Problema Subsir crescator maximal Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
using namespace std;

const int MAXN = 100000;

int sir[MAXN+1], best[MAXN+1], last[MAXN+1], lgmax, N, poz;

void citire()
{
    scanf("%d",&N);
    for(int i = 1; i<= N; i++)
        scanf("%d",&sir[ i ]);
}

int cautBin(int left, int right, int x)
{
    int p = -1;

    while( left <= right )
    {
        int m = ( left + right )/2;

        if( last[ m ] < x )
            p = m, left = m + 1;
        else right = m - 1;
    }

    return p;
}

void solve()
{
    best[ 1 ] = 1; last[ 1 ] = sir[ 1 ]; poz = 1;

    for(int i = 1; i <= N; i++)
    {
        if( sir[ i ] > last[ lgmax ] )
            lgmax++, last[ lgmax ] = sir[ i ], best[ i ] = lgmax, poz = i;
        else if( sir[ i ] < last[ 1 ] )
            best[ i ] = 1, last[ 1 ] = sir[ i ];
        else
        {
            int p = cautBin( 1, lgmax, sir[ i ] );
            last[ p + 1 ] = sir[ i ], best[ i ] = best[ p ] + 1;
        }
    }
}

void genTest(int N)
{
    srand( time( NULL ) );
    cout<<N<<endl;
    for(int i = 1; i <= N; i++)
        cout<<rand()%20<<' ';
}

void printSol()
{
    deque <int> sol;
    int last = sir[ poz ];
    sol.push_back( last );
    lgmax--;

    for(int i = poz; i >= 1; i--)
        if( best[ i ] == lgmax && sir[ i ] < sir[ poz ] )
        {
            sol.push_front( sir[ i ] );
            poz = i;
            lgmax--;
        }

    for(int i = 0; i < sol.size(); i++)
        printf("%d ",sol[ i ]);
        //cout<<sol[ i ]<<' ';
}

void testSolve()
{
    solve();
    //cout<<lgmax<<endl;
    printf("%d\n",lgmax);
    printSol();
}


int main()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);

    citire();


    //genTest( 10 );
    testSolve();
    return 0;
}