Cod sursa(job #1702697)

Utilizator GilgodRobert B Gilgod Data 15 mai 2016 14:30:50
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <iostream>
#include <fstream>
#include <assert.h>

const char IN[] = "scmax.in", OUT[] = "scmax.out";
const int NMAX = 100001;
const int INF = 0x3f3f3f3f;

inline int maximal(int a, int b) { return ((a) > (b)) ? (a) : (b); }

using namespace std;

int V[NMAX];
int N;

int maxCandidate;

int PI[NMAX];
int BST[NMAX];
int L[NMAX]; //L[x] = indice in v a val pentru o secventa de lung x

inline void read_data() {
	assert(freopen(IN, "r", stdin));
	assert(scanf("%d", &N));
	for (int i = 1; i <= N; ++i) {
		assert(scanf("%d", &V[i]));
	}
	fclose(stdin);
}

int binary_search(int x) {
	//cautare binara dupa lungimea secventei
	//daca gaseste atunci e o noua varianta de a obtine o lungime
	//din ce am calculat anterior
	int low = 0, high = maxCandidate;
	while (low <= high) {
		int m = low + (high - low) / 2;
		if (V[L[m]] < x && V[L[m + 1]] >= x) return m;
		else if (V[L[m + 1]] < x) {
			//caut in dreapta dupa o secventa mai lunga
			low = m + 1;
		}
		else {
			//caut in stanga
			high = m - 1;
		}
	}
	//daca nu gaseste, inseamna ca se poate adauga la secventa maxima curenta
	return maxCandidate;
}

void print_res(int x) {
	if (x == 0) return;
	print_res(PI[x]);
	printf("%d ", V[x]);
}

void PD() {
	BST[1] = 1, PI[1] = 0, L[1] = 1;
	maxCandidate = 1;
	int end = -1;
	int max = -INF;
	for (int i = 2; i <= N; ++i) {
		int len = binary_search(V[i]);
		PI[i] = L[len];
		BST[i] = len + 1;
		if (max < len + 1) { max = len + 1; end = i; }
		L[len + 1] = i;
		maxCandidate = maximal(maxCandidate, len + 1);
	}
	printf("%d\n", max);
	print_res(end);
}

int main() {
	read_data();
	assert(freopen(OUT, "w", stdout));
	PD();
	fclose(stdout);
	return 0;
}