Cod sursa(job #388858)

Utilizator RegeleUmbrelorPopescu Mihai RegeleUmbrelor Data 31 ianuarie 2010 10:55:10
Problema Subsir crescator maximal Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
using namespace std;
#include<stdio.h>
const int NMAX=100005;
int n, v[NMAX],x[NMAX], pred[NMAX], s[NMAX],lmax;/* v-elementele, x[i]=pozitia celui mai mic element 
care poate fi ultimul intr-un subsir crescator de lungime i; pred[i]=pozitia predecesorului 
elementului i in subsirul format; s[i]=lungimea celui mai lung subsir crescator maximal care 
se poate forma avand ca ultim element v[i];*/

void RUinit()
{
	freopen("scmax.in", "r",stdin);
	freopen("scmax.out", "w",stdout);
	scanf("%d", &n);
	for(int i=1;i<=n;++i)
		scanf("%d", &v[i]);
	s[1]=1;x[1]=1;lmax=1;
}

int RUbin(int i)
{
	int u=0,pas=1;
	if(v[i]<v[x[1]])
		return 1;
	while(v[x[u+pas]]<v[i])
	{
		pas<<1;
		if(v[x[u+pas-1]]<v[i] && v[x[u+pas]]>=v[i])
			return u+pas;
		if(v[x[u+pas-1]]>=v[i] || u+pas>=lmax)
		{	
			u+=pas>>1;pas=1;
		}
	}
}
	
void RUrez()
{
	int t;
	for(int i=2;i<=n;++i)
	{
		if(v[i]>v[i-1])
		{	
			s[i]=s[i-1]+1;
			x[s[i]]=i;
			pred[i]=i-1;
			if(lmax<s[i])
				lmax=s[i];
		}
		if(v[i]<v[i-1])
		{
			t=RUbin(i);
			if(v[x[t]]!=v[i])
				x[t]=i;
			pred[i]=x[t-1];
			s[i]=t;
		}
		if(v[i]==v[i-1])
		{	
			s[i]=s[i-1];
			pred[i]=pred[i-1];
		}
	}
}

int RUvector(int lmax, int k)
{
	while(lmax)
			{	
				s[--lmax]=v[pred[k]];
				k=pred[k];
			}
}

void RUafis()
{
	int k=0;
	printf("%d\n", lmax);
	for(int i=1;i<=n;++i)
		if(s[i]==lmax)
		{	
			s[lmax]=v[i];k=i;
			RUvector(lmax, k);
			i=n;
		}
	for(k=1;k<=lmax;++k)
		printf("%d ", s[k]);
}

int main()
{
	RUinit();
	RUrez();
	RUafis();
	return 0;
}