Cod sursa(job #1680451)

Utilizator monicalegendaLegenda Monica monicalegenda Data 8 aprilie 2016 19:35:35
Problema Subsir crescator maximal Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

int best[100001], parent[100001], lengths[100001], c_maxlen;
long long v[100001];

void afis(int i){
	if(parent[i] != 0){
		afis(parent[i]);
	}
	fout << v[i] << ' ';
}

int cbin(int start, int stop, int val){
	// gaseste cea mai mare lungime a unui subsir care se termina in ceva mai
	// mic decat val

	// lengths[i] = pozitia in v a minimului ultim elem al unui subsir care are
	// 				lungimea i => v[lengths[]] este sortat crescator

	if(start > stop){ // toti au fost mai mici
		return c_maxlen;
	}

	int m = start + (stop - start) / 2;

	if(v[lengths[m]] < val && v[lengths[m + 1]] >= val){
		// cel cu lungimea m e ok, cu lungime mai mare nu avem
		return m;
	}

	if(v[lengths[m + 1]] < val){
		// poate gasim unele cu lungimi mai mari
		return cbin(m + 1, stop, val);
	}

	// trebuie sa cautam unele cu lungimi mai mici decat m
	return cbin(start, m - 1, val);
}

int main(){

	int n, i, maxl_ant;

	fin >> n;
	for(i = 1; i <= n; i++){
		fin >> v[i];
	}

	best[1] = 1;
	parent[1] = 1;
	lengths[1] = 1;
	lengths[0] = 0;
	c_maxlen = 1;

	for(i = 2; i <= n; i++){
		maxl_ant = cbin(0, c_maxlen, v[i]);
		best[i] = maxl_ant + 1;
		parent[i] = lengths[maxl_ant];
		lengths[maxl_ant + 1] = i;
		if(c_maxlen < maxl_ant + 1){
			c_maxlen = maxl_ant + 1;
		}
	}

	fout << c_maxlen << '\n';
	afis(lengths[c_maxlen]);

	return 0;
}