Cod sursa(job #2153233)

Utilizator aurelionutAurel Popa aurelionut Data 6 martie 2018 01:29:52
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <vector>

using namespace std;

const int INF = 2000000000;
const int DIM = 100010;
pair <int, int> v[DIM];
int dp[DIM], n;
int aint[4 * DIM], ans, pos;
int a[DIM];
vector <int> sol;
unordered_map <int, int> viz;
ifstream fin("scmax.in");
ofstream fout("scmax.out");

inline int LeftSon(const int& x)
{
	return 2 * x;
}

inline int RightSon(const int& x)
{
	return 2 * x + 1;
}

void Update(int node, int left, int right, int val, int pos)
{
	if (left == right)
	{
		aint[node] = val;
		return;
	}
	int mid = (left + right) / 2;
	if (pos <= mid)
		Update(LeftSon(node), left, mid, val, pos);
	else
		Update(RightSon(node), mid + 1, right, val, pos);
	aint[node] = max(aint[LeftSon(node)], aint[RightSon(node)]);
}

void Query(int node, int left, int right, const int& LeftQuery, const int& RightQuery)
{
	if (LeftQuery <= left && right <= RightQuery)
	{
		ans = max(ans, aint[node]);
		return;
	}
	int mid = (left + right) / 2;
	if (LeftQuery <= mid)
		Query(LeftSon(node), left, mid, LeftQuery, RightQuery);
	if (RightQuery >= mid + 1)
		Query(RightSon(node), mid + 1, right, LeftQuery, RightQuery);
}

void Read()
{
	fin >> n;
	for (int i = 1;i <= n;++i)
	{
		fin >> v[i].first;
		a[i] = v[i].first;
		v[i].second = i;
	}
	fin.close();
}

inline void Normalizare()
{
	sort(v + 1, v + n + 1);
	int val = 0;
	pair <int, int> aux[DIM];
	for (int i = 1;i <= n;++i)
	{
		aux[i].first = v[i].second;
		if (viz[v[i].first] == 0)
		{
			aux[i].second = ++val;
			viz[v[i].first] = val;
		}
		else
		{
			aux[i].second = viz[v[i].first];
		}
	}
	sort(aux + 1, aux + n + 1);
	for (int i = 1;i <= n;++i)
		v[i].second = aux[i].second;
}

void Solve()
{
	dp[1] = 1;
	Update(1, 1, n, 1, v[1].second);
	for (int i = 2;i <= n;++i)
	{
		ans = 0;
		if (v[i].second - 1 >= 1)
			Query(1, 1, n, 1, v[i].second - 1);
		dp[i] = ans + 1;
		Update(1, 1, n, dp[i], v[i].second);
	}
}

void Write()
{
	int x = -1;
	for (int i = 1;i <= n;++i)
		x = max(x, dp[i]);
	fout << x << "\n";
	for (int i = n;i >= 1;--i)
	{
		if (dp[i] == x)
		{
			sol.push_back(a[i]);
			--x;
		}
	}
	reverse(sol.begin(), sol.end());
	for (vector <int> ::iterator it = sol.begin();it != sol.end();++it)
		fout << *it << " ";
	fout.close();
}

int main()
{
	Read();
	Normalizare();
	Solve();
	Write();
	return 0;
}