Cod sursa(job #876150)

Utilizator paul_gabryelPaul Buda paul_gabryel Data 11 februarie 2013 13:33:43
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb

#include <cstdio>
#include <fstream>
#include <algorithm>

using namespace std;

const int N = 100005;

int A[N],ind[N],SA[N];
int n,L[N],P,S;
int ADI[N<<2],QUE[N];

void READ ()
{
	
	ifstream in ("scmax.in");
	in>>n;
	
	for(int i=1;i<=n;++i)
	{
		in>>A[i];
		ind[i]=SA[i]=A[i];
	}
	
}

void QUERY (int nod,int ft,int bk,int st)
{
	
	if( st <= ft && bk <= n )
	{
	
		if( L[ADI[nod]] >= S )
		{
			S=L[ADI[nod]];
			P=ADI[nod];
		}
	
		return;
	}
	
	int mid=(ft+bk)>>1;
	
	if( mid >= st )
		QUERY( nod<<1 , ft , mid , st );
	
	if( mid < n )
		QUERY( (nod<<1)+1 , mid+1 , bk , st);
	
}

void UPDATE (int nod,int ft,int bk)
{
	
	if( ft == bk )
	{
		ADI[nod]=S;
		return;
	}
	
	int mid=(ft+bk)>>1;
	if( mid >= P )
		UPDATE ( nod<<1 , ft , mid );
	else
		UPDATE ( (nod<<1)+1 , mid+1 , bk );
		
	if( L[ADI[nod<<1]] > L[ADI[(nod<<1)+1]] )
		ADI[nod]=ADI[nod<<1];
	else
		ADI[nod]=ADI[(nod<<1)+1];
	
}

void SOLVE ()
{
	
	sort(SA+1,SA+n+1);
	
	int m=1;
	
	for(int i=2;i<=n;++i)
		if(SA[m]!=SA[i])
			SA[++m]=SA[i];
	
	for(int i=1;i<=n;++i)
		ind[i]=lower_bound(SA+1,SA+m+1,ind[i])-SA;
		
	for(int i=n;i;--i)
	{
		P = 0 ;
		S = 0 ;
		QUERY ( 1 , 1 , n , ind[i]+1 );
		QUE[i]=P;
		L[i]=L[P]+1;
		P=ind[i];
		S=i;
		UPDATE ( 1 , 1 , n );
	}
	
	P=0;
	
	for(int i=1;i<=n;++i)
		if( L[i] > L[P] )
			P=i;
	
}

void OUT ()
{
	
	freopen("scmax.out","w",stdout);
	printf("%d\n",L[P]);
	for( int i=P ; i ; i=QUE[i] )
		printf("%d ",A[i]);
	
}

int main ()
{
	
	READ ();
	SOLVE ();
	OUT ();
	
	return 0;
	
}