Cod sursa(job #640019)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 24 noiembrie 2011 16:35:43
Problema Subsir crescator maximal Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <algorithm>
using namespace std;
#define lsb (x & -x)

ifstream fi ("scmax.in");
ofstream fo ("scmax.out");

const int dim = 100005;
int A[dim], R[dim], aib[dim], L[dim], D[dim], T[dim];
int N, mx, nL;

int cauta (int p, int u, int val)
{
	int m;
	while (p <= u)
	{
		m = (p + u) >> 1;
		if (L[m] < val)
			p = m + 1;
		else
			u = m - 1;
	}
	return p;
}

void update (int x, int i)
{
	for (; x <= N; x += lsb)
		if (D[i] > D[aib[x]])
			aib[x] = i;
}

int query (int x)
{
	int r = 0;
	for (; x > 0; x -= lsb)
		if (D[r] < D[aib[x]])
			r = aib[x];
	return r;
}

void cit ()
{
	fi >> N;
	for (int i = 1; i <= N; i++)
	{
		fi >> A[i];
		L[i] = A[i];
	}
	
	sort (L+1, L+N+1);	
	for (int i = 1; i <= N; i++)
		if (L[i] != L[nL])
			L[++nL] = L[i];
	
	for (int i = 1; i <= N; i++)
		R[i] = cauta (1, nL, A[i]);
}

void rez ()
{
	for (int i = 1; i <= N; i++)
	{
		T[i] = query (R[i] - 1);
		D[i] = D[ T[i] ] + 1;
		update (R[i], i);
	}
	
	for (int i = 1; i <= N; i++)
		if (D[mx] < D[i])
			mx = i;
	
	nL = D[mx];
	for (int i = mx; T[i] != 0; i = T[i])
		L[nL--] = A[i];
}

void afi ()
{
	fo << D[mx] << '\n';
	for (int i = 1; i <= D[mx]; i++)
		fo << L[i] << ' ';
}

int main ()
{
	cit ();
	rez ();
	afi ();
	
	return 0;
}