Cod sursa(job #781129)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 23 august 2012 14:51:17
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
// O(n * log k)

#include <cstdio>

const unsigned int MAX_SIZE(100000);

unsigned int vector [MAX_SIZE];
unsigned int substring [MAX_SIZE];
unsigned int pred [MAX_SIZE];

inline unsigned int maximum_increasing_substring (unsigned int size)
{
	unsigned int *tail(substring), index(1), number;
	unsigned int left, right, middle;
	do
	{
		if (vector[*tail] < vector[index])
		{
			pred[index] = *tail;
			++tail;
			*tail = index;
		}
		else
		{
			left = 0;
			right = tail - substring;
			number = vector[index];
			while (left < right)
			{
				middle = (left + right) >> 1;
				if (number > vector[substring[middle]])
					left = middle + 1;
				else
					right = middle;
			}
			if (vector[substring[left]] > number)
			{
				if (left > 0)
					pred[index] = substring[left - 1];
				substring[left] = index;
			}
		}
		++index;
	}
	while (index < size);
	size = tail - substring + 1;
	if (size > 1)
	{
		unsigned int previous(pred[*tail]);
		--tail;
		while (true)
		{
			*tail = previous;
			if (tail == substring)
				break;
			previous = pred[*tail];
			--tail;
		}
	}
	return size;
}

int main (void)
{
	std::freopen("scmax.in","r",stdin);
	std::freopen("scmax.out","w",stdout);
	unsigned int n;
	std::scanf("%u",&n);
	unsigned int *iterator(vector), *end(vector + n);
	do
	{
		std::scanf("%u",iterator);
		++iterator;
	}
	while (iterator < end);
	std::fclose(stdin);
	unsigned int length(maximum_increasing_substring(n));
	iterator = substring;
	end = substring + length - 1;
	std::printf("%u\n",length);
	while (true)
	{
		std::printf("%u",vector[*iterator]);
		if (iterator == end)
			break;
		std::putchar(' ');
		++iterator;
	}
	std::putchar('\n');
	std::fclose(stdout);
	return 0;
}