Cod sursa(job #410394)

Utilizator laserbeamBalan Catalin laserbeam Data 4 martie 2010 12:34:44
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
// Catalin Balan
// Thu Mar  4 12:06:51 EET 2010
// Subsir Crescator Maximal - N log N

#include <cstdio>
#include <cstdlib>

using namespace std;

#define	NMAX 100003
#define CHUNK 8192

#define FIN "scmax.in"
#define FOUT "scmax.out"

char g_buf[CHUNK];
int g_p=CHUNK-1;

inline int get()
{

	int x = 0;
	while (g_buf[g_p] < '0' || g_buf[g_p] > '9')
		if (++g_p == CHUNK) fread(g_buf,1,CHUNK,stdin), g_p=0;

	while (g_buf[g_p] >= '0' && g_buf[g_p] <= '9')
	{
		x = x*10 + g_buf[g_p]-'0';
		if (++g_p == CHUNK) fread(g_buf,1,CHUNK,stdin), g_p=0;
	}
	return x;
}

int n, max;
int a[NMAX];		// vectorul cu elementele
int tata[NMAX];		// predecesorii elementelor
int cine[NMAX];		// pozitia elementului minim ce termina un subsir pe pozitia i


int cauta( int val )
{
	int st, dr, m;
	st = 0; dr = max;
	while ( st <= dr )
	{
		m = (st+dr)>>1;
		if ( a[cine[m]] < val && a[cine[m+1]] >= val ) return m;
		if ( a[cine[m]] < val ) st = m+1;
		else 					dr = m-1;
	}
	return max;
}

void afis_rec( int p )
{
	if ( tata[p] ) afis_rec( tata[p] );
	printf("%d ", a[p]);
}

int main(int argv, char ** argc)
{
	freopen(FIN, "r", stdin);
	freopen(FOUT, "w", stdout);

	n = get();
	for (int i = 1; i <= n; ++i) a[i] = get();

	tata[1] = 0;
	cine[1] = 1;
	max = 1;

	int poz;
	for (int i = 2; i <= n; ++i)
	{
		poz 		= cauta( a[i] );
		cine[poz+1] = i;
		tata[i] 	= cine[poz];
		if (poz == max) ++max;
	}

	printf("%d\n", max);
	afis_rec( cine[max] );

	
	return EXIT_SUCCESS;
}