Cod sursa(job #2200100)

Utilizator emiemiEmi Necula emiemi Data 30 aprilie 2018 12:35:49
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <fstream>
#include <algorithm>

using namespace std;
ifstream f("scmax.in");
ofstream g("scmax.out");

#define maxN 100005

int n, i, len, ant, d, maxi, poz, val, ord[maxN], v[maxN], D[maxN], h[400010];

void update(int stg, int dr, int nod) {
	if (stg == dr) {
		h[nod] = max(h[nod], val);
		return;
	}

	int mij = (stg + dr) / 2;
	if (mij >= poz) {
		update(stg, mij, 2 * nod);
	} else {
		update(mij + 1, dr, 2 * nod + 1);
	}

	h[nod] = max(h[2 * nod], h[2 * nod + 1]);
}

void query(int stg, int dr, int nod) {
	if (dr <= poz) {
		val = max(val, h[nod]);
		return;
	}
	
	int mij = (stg + dr) / 2;
	if (poz > mij)
		query(mij + 1, dr, 2 * nod + 1);
	query(stg, mij, 2 * nod);
}

void printRec(int value) {
	if (value == 0)
		return;
	while (D[i] != value || v[i] >= ant)
		--i;
	int poz = i;
	ant = v[poz];
	--i;
	printRec(value - 1);
	g << ord[v[poz]] << ' ';
}

int main() {
	f >> n;
	for (i = 1; i <= n; ++i) {
		f >> v[i];
		ord[i] = v[i];
	}

	sort(ord + 1, ord + n + 1);
	len = 1;
	for (i = 2; i <= n; ++i)
		if (ord[len] != ord[i])
			ord[++len] = ord[i];

	for (i = 1; i <= n; ++i)
		v[i] = lower_bound(ord + 1, ord + len + 1, v[i]) - ord;

	D[1] = 1;
	maxi = 1;
	poz = v[1];
	val = 1;
	update(1, len, 1);
	for (i = 2; i <= n; ++i) {
		poz = v[i] - 1;
		val = 0;
		if (poz > 0)
			query(1, len, 1);
		++val;

		D[i] = val;
		if (D[i] > maxi)
			maxi = D[i];

		poz = v[i];
		update(1, len, 1);
	}

	g << maxi << '\n';
	i = n;
	ant = 2000000001;
	printRec(maxi);
	g << '\n';

	return 0;
}