Cod sursa(job #938193)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 11 aprilie 2013 23:49:12
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <algorithm>
#define MAX_N 100004
using namespace std;
const char iname[] = "scmax.in";
const char oname[] = "scmax.out";
ifstream fin(iname);
ofstream fout(oname);
struct sweep{
	int v, poz;
}x[MAX_N];
struct cmp
{
	bool operator() (const sweep &b, const sweep &c)
	{
		if (b.v < c.v) return 1; 
		return 0;
	};
};
int N, i, j, foo, poz, ANS;
int v[MAX_N], H[MAX_N * 3];
int a[MAX_N], best[MAX_N], t[MAX_N];
int sol[MAX_N];
inline int binary_search (int val)
{
	int mid = 0, st = 0, dr = N, poz_min;
	while (st <= dr)
	{
		mid = (st + dr) / 2;
		if (x[mid].v == val)
			st = mid + 1,
			poz_min = x[mid].poz;
		else
		{
			if (x[mid].v < val) st = mid + 1;
			else 
				dr = mid - 1;
		}
	}
	return poz_min;
}
inline void update (int node, int left, int right, int p, int ind)
{
	if (left >= right)
	{
		H[node] = ind;
		return;
	}
	int m = (left + right) / 2, L = node << 1, R = L | 1;
	if (p <= m) update (L, left, m, p, ind);
	else 
		update (R, m + 1, right, p, ind);
	if (best[H[L]] > best[H[R]]) H[node] = H[L];
	else H[node] = H[R];
}
inline void query (int node, int left, int right, int i, int j)
{
	if (i <= left && right <= j)
	{
		if (best[H[node]] > best[poz])
			poz = H[node];
		return;
	}
	int m = (left + right) / 2, L = node << 1, R = L | 1;
	if (i <= m) query (L, left, m, i, j);
	if (j > m) query (R, m + 1, right, i, j);
}
int main()
{
	fin >> N;
	for (i = 1; i <= N; ++i) fin >> v[i], x[i].v = v[i];
	sort (x + 1, x + N + 1, cmp());
	for (i = 1; i <= N; ++i)
	{
		if (x[i].v == x[i - 1].v) x[i].poz = x[i - 1].poz;
		else 
			x[i].poz = ++foo;
	}
	for (i = 1; i <= N; ++i)
	{
		if (v[i] == v[i - 1]) a[i] = a[i - 1];
		else
			a[i] = binary_search(v[i]);
	}
	best[1] = 1;
	update (1, 1, foo, a[1], 1);
	for (i = 2; i <= N; ++i)
	{
		poz = 0;
		if (a[i] - 1 > 0)
			query (1, 1, foo, 1, a[i] - 1);
		best[i] = best[poz] + 1;
		t[i] = poz;
		update (1, 1, foo, a[i], i);
	}
	for (i = 1; i <= N; ++i) if (best[i] > ANS) ANS = best[i], poz = i;
	fout << ANS << '\n';
	i = poz;
	while (i > 0)
	{
		sol[++j] = v[i];
		i = t[i];
	}
	for (i = j; i >= 1; --i)
		fout << sol[i] << ' ';
	fout << '\n';
	return 0;
}