Cod sursa(job #809148)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 7 noiembrie 2012 22:16:57
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb

#include <cstdio>
#include <algorithm>

const int MAX_SIZE(1000001);

int n, max_length, last_index, max_values;
int v [MAX_SIZE];
int u [MAX_SIZE];
int sorted [MAX_SIZE];
int length [MAX_SIZE];
int bit [MAX_SIZE];

inline int lsb (int x)
{
	return x & (-x);
}

inline void update (int x, int index)
{
	while (x <= n)
	{
		if (length[index] > length[bit[x]])
			bit[x] = index;
		else
			break;
		x += lsb(x);
	}
}

inline int query (int x)
{
	int max(0);
	while (x)
	{
		if (length[bit[x]] > length[max])
			max = bit[x];
		x -= lsb(x);
	}
	return max;
}

inline void read (void)
{
	std::freopen("scmax.in","r",stdin);
	std::scanf("%d",&n);
	for (int *iterator(v + 1), *end(v + n) ; iterator <= end ; ++iterator)
		std::scanf("%d",iterator);
	std::fclose(stdin);
}

inline void unique_values (void)
{
	int i, j;
	for (j = 1, i = 2 ; i <= n ; ++i)
		if (u[j] != u[i])
		{
			++j;
			u[j] = u[i];
		}
	max_values = j;
}

inline void normalize (void)
{
	for (int i(1) ; i <= n ; ++i)
		sorted[i] = std::lower_bound(u + 1,u + max_values + 1,v[i]) - u;
}

inline void maximum_incresing_substring (void)
{
	for (int i(1) ; i <= n ; ++i)
	{
		length[i] = length[query(sorted[i] - 1)] + 1;
		update(sorted[i],i);
		if (length[i] > max_length)
		{
			max_length = length[i];
			last_index = i;
		}
	}
}

inline void print (void)
{
	std::freopen("scmax.out","w",stdout);
	std::printf("%d\n",max_length);
	int i(max_length);
	sorted[max_length] = v[last_index];
	for (int i(last_index - 1) ; i && max_length ; --i)
	{
		if (length[i] == max_length - 1 && v[i] < v[last_index])
		{
			--max_length;
			sorted[max_length] = v[i];
			last_index = i;
		}
	}
	for (int j(1) ; j <= i ; ++j)
		std::printf("%d ",sorted[j]);
	std::putchar('\n');
	std::fclose(stdout);
}

int main (void)
{
	read();
	for (int i(1) ; i <= n ; ++i)
		u[i] = v[i];
	std::sort(u + 1, u + n + 1);
	unique_values();
	normalize();
	maximum_incresing_substring();
	print();
	return 0;
}