Cod sursa(job #2153231)

Utilizator trifangrobertRobert Trifan trifangrobert Data 6 martie 2018 01:27:15
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#include <algorithm>
#include <vector>

#define limit 5010
#define ch (buffer[position])
#define Next (++position == limit) ? (fin.read(buffer, limit), position = 0) : 0

using namespace std;

char buffer[limit];
int position = 0;

const int DIM = 100010;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
int aib[DIM];
int n, v[DIM], dp[DIM];
pair <int, int> a[DIM];
pair <int, int> b[DIM];
int elmax = -1;
int Max = -1;
int sol[DIM];

void Read(int &x)
{
	for (;!('0' <= ch && ch <= '9');Next);
	for (x = 0;('0' <= ch && ch <= '9');x = x * 10 + (ch - '0'), Next);
}

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

void Normalizare()
{
	for (int i = 1;i <= n;++i)
		a[i] = make_pair(v[i], i);
	sort(a + 1, a + n + 1);
	int val = 0;
	a[0].first = -1;
	for (int i = 1;i <= n;++i)
	{
		if (a[i].first != a[i - 1].first)
			b[i] = make_pair(a[i].second, ++val);
		else
			b[i] = make_pair(a[i].second, val);
	}
	elmax = val;
	sort(b + 1, b + n + 1);
}

void Update(int pos, int val)
{
	for (int i = pos;i <= elmax;i += (i & (-i)))
		if (aib[i] < val)
			aib[i] = val;
		else
			break;
}

int Query(int val)
{
	int ret = 0;
	for (int i = val;i >= 1;i -= (i & (-i)))
		ret = max(ret, aib[i]);
	return ret;
}

void Solve()
{
	for (int i = 1;i <= n;++i)
	{
		dp[i] = 1 + Query(b[i].second - 1);
		Update(b[i].second, dp[i]);
	}

	int x = -1;
	for (int i = 1;i <= n;++i)
		x = max(x, dp[i]);
	sol[0] = x;
	for (int i = n;i >= 1;--i)
	{
		if (x == dp[i])
		{
			sol[x] = v[i];
			--x;
		}
	}
}

void Write()
{
	fout << sol[0] << "\n";
	for (int i = 1;i <= sol[0];++i)
		fout << sol[i] << " ";
	fout.close();
}

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