Cod sursa(job #364609)

Utilizator FlorianFlorian Marcu Florian Data 16 noiembrie 2009 16:31:06
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.1 kb
using namespace std;
#include<cstdio>
#include<algorithm>
#define MAX_N 100002
int AIB[MAX_N], a[MAX_N], bst[MAX_N],N, M, v[MAX_N], lst[MAX_N], pre[MAX_N];
void update(int x, int i) // fac update pe intervalele care contin x
{
	for(;x <= N; x+= (x & -x))
		if(bst[AIB[x]] < bst[i]) AIB[x] = i; 
}
int query(int x) // returnez maximul dintre intervalele care contin x
{
	int mx = 0;
	for(;x;x -= (x & -x))
		if( bst[AIB[x]] > bst[mx] ) mx = AIB[x];
	return mx;
}
inline void print(int i)
{
	if(pre[i]) print(pre[i]);
	printf("%d ",a[i]);
}
int main()
{
	int i,j,psol = 0;
	freopen("scmax.in","r",stdin);
	freopen("scmax.out","w",stdout);
	scanf("%d",&N);
	for(i = 1; i<=N; ++i)
	{
		scanf("%d",&a[i]);
		lst[i] = a[i];
	}
	sort(lst + 1, lst+N+1);
	for( i = 1; i<=N; ++i)
		if(lst[M] != lst[i]) lst[++M] = lst[i];
	for(i=1;i<=N;++i)
		v[i] = lower_bound(lst+1,lst+M+1, a[i]) - lst;
	for(i = 1; i<=N; ++i)
	{
		pre[i] = query(v[i] - 1);
		bst[i] = bst[pre[i]] + 1;
		update(v[i], i);
		if(bst[i] > bst[psol]) psol = i; 
	}
	printf("%d\n",bst[psol]);
	print(psol);
	return 0;
}