Cod sursa(job #898531)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 28 februarie 2013 10:35:59
Problema Secv Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.28 kb

#include <cstdio>
#include <algorithm>

const int MAX_SIZE(5001);

int n, l, m, end, start;
int v [MAX_SIZE];
int a [MAX_SIZE];
int b [MAX_SIZE];
int p [MAX_SIZE];

inline void read (void)
{
	std::freopen("secv.in","r",stdin);
	std::scanf("%d",&n);
	for (int i(1) ; i <= n ; ++i)
	{
		std::scanf("%d",&v[i]);
		a[i] = v[i];
	}
	std::fclose(stdin);
}

inline void print (void)
{
	std::freopen("secv.out","w",stdout);
	if (l == m)
		std::printf("%d\n",end - start + 1);
	else
		std::printf("-1\n");
	std::fclose(stdout);
}

inline void greedy (void)
{
	std::sort(a + 1,a + n + 1);
	int i, j;
	for (i = 1, j = 1 ; i <= n ; ++i)
		if (a[i] != a[i - 1] || i == 1)
		{
			a[j] = a[i];
			++j;
		}
	m = j - 1;
	int left, right, middle;
	for (i = 1 ; i <= n ; ++i)
	{
		if (v[i] > v[b[l]] || !l)
		{
			++l;
			b[l] = i;
			p[i] = b[l - 1];
			continue;
		}
		if (v[i] == v[i - 1])
			continue;
		left = 1;
		right = l;
		middle = (left + right) >> 1;
		while (left < right)
		{
			if (v[i] > v[b[middle]])
				left = middle + 1;
			else
				right = middle;
			middle = (left + right) >> 1;
		}
		if (v[i] <= v[b[middle]])
		{
			b[middle] = i;
			p[i] = b[middle - 1];
		}
	}
	end = b[l];
	for (i = b[l] ; p[i] ; i = p[i])
		/* do nothing */;
	start = i;
}

int main (void)
{
	read();
	greedy();
	print();
	return 0;
}