Cod sursa(job #2035792)

Utilizator robuvedVictor Robu robuved Data 9 octombrie 2017 20:22:55
Problema Subsir crescator maximal Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include <fstream>
#include <stack>
#include <algorithm>
using namespace std;

ifstream in("scmax.in");
ofstream out("scmax.out");
#define MAX 100000
int v[MAX + 1], vsorted[MAX + 1], dp[MAX + 1], pr[MAX + 1], BIT[MAX + 1], order[MAX + 1];
int N;
int NU;
void Update(int x, int poz)
{
	for (; x <= NU; x += x & -x)
	{
		if (dp[BIT[x]] < dp[poz])
		{
			BIT[x] = poz;
		}
	}
}
int Query(int x)
{
	int mx = 0;
	for (;x; x -= x & -x)
	{
		if (dp[mx] < dp[BIT[x]])
		{
			mx = BIT[x];
		}
	}
	return mx;
}
int main()
{
	in >> N;
	for (int i = 1; i <= N; i++)
	{
		in >> v[i];
		vsorted[i] = v[i];
	}
	sort(vsorted + 1, vsorted + N + 1);
	
	NU = unique(vsorted + 1, vsorted + N + 1) - vsorted - 1;
	
	for (int i = 1; i <= N; i++)
	{
		order[i] = lower_bound(vsorted + 1, vsorted + NU + 1, v[i]) - vsorted;
	}
	
	for (int i = 1; i <= N; i++)
	{
		int pred = pr[i] = Query(order[i] - 1);
		dp[i] = dp[pred] + 1;
		Update(order[i], i);
	}

	int max_i = BIT[NU];


	out << dp[max_i] << '\n';
	stack<int> s;
	s.push(v[max_i]);

	while (pr[max_i] > 0)
	{
		max_i = pr[max_i];
		s.push(v[max_i]);
	}
	while (!s.empty())
	{
		out << s.top() << ' ';
		s.pop();
	}
}