Cod sursa(job #627849)

Utilizator paul24090FMI - Balauru Paul paul24090 Data 30 octombrie 2011 19:48:56
Problema Subsir crescator maximal Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int NMax = 100002;
int n,nN;
int v[NMax],vN[NMax],best[NMax],v2[NMax],AIB[NMax],t[NMax];

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

void normalizare()
{
	for(int i=1;i<=n;i++)
		v2[i]=vN[i]=v[i];
	sort(vN+1,vN+n+1);
	nN=1;
	for(int i=2;i<=n;i++)
		if(vN[i]!=vN[nN])
			vN[++nN]=vN[i];
	for(int i=1;i<=n;i++)
		v[i]=lower_bound(vN+1,vN+nN+1,v[i])-vN;
}

void afisare2(int k)
{
	if(k==0)
		return;
	else afisare2(t[k]);
	printf("%d ",v2[k]);
}

void afisare()
{
	int bst=0,ind=0;
	for(int i=1;i<=n;i++)
		if(bst<best[i])
		{
			bst=best[i];
			ind=i;
		}
	/*for(int i=1;i<=n;i++)
		printf("%d ",v[i]);
	printf("\n");*/
	printf("%d\n",bst);
	afisare2(ind);
}

int query(int k)
{
	int max=0;
	for(;k>=1;k-=(k&(k-1))^k)
	{
		if(max<best[AIB[k]])
			max=AIB[k];
	}
	return max;
}

void update(int ind,int k)
{
	for(;k<=nN;k+=(k&(k-1))^k)
	if(best[AIB[k]]<best[ind])
		AIB[k]=ind;
}

int main()
{
	freopen("scmax.in","rt",stdin);
	freopen("scmax.out","wt",stdout);
	citire();
	normalizare();
	best[1]=1;
	AIB[v[1]]=1;
	for(int i=2;i<=n;i++)
	{
		t[i]=query(v[i]-1);
		best[i]=best[t[i]]+1;
		update(i,v[i]);
	}
	afisare();
	return 0;
}