Cod sursa(job #634847)

Utilizator nandoLicker Nandor nando Data 17 noiembrie 2011 15:43:08
Problema Subsir crescator maximal Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <map>
using namespace std;

fstream fin("scmax.in", ios::in);
fstream fout("scmax.out", ios::out);

#define MAXN 100100
#define zero(x) (x ^ (x - 1) & x)
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))

int n, nv = 1;
int a[MAXN], b[MAXN], arb[MAXN * 5], len[MAXN], prev[MAXN];

void normalize()
{
	map<int, int> values;
	
	sort (arb + 1, arb + n + 1);
	for (int i = 1; i <= n; ++i) {
		if (values.find(arb[i]) == values.end()) {
			values[arb[i]] = nv++;
		}	
	}
	
	for (int i = 1; i <= n; ++i) {
		b[i] = values[a[i]];
		len[b[i]] = 1;	
		arb[i] = 1;
	}
	
	--nv;
}

int query (int node, int left, int right, int a, int b)
{
	if (a > b) {
		return 0;	
	}
	
	if (a <= left && right <= b) {
		return arb[node];	
	}
	
	int mdl = left + ((right - left) >> 1), maxv = 0;
	
	if (a <= mdl) {
		maxv = query(node << 1, left, mdl, a, b);
	}
	
	if (b > mdl) {
		int nv = query ((node << 1) + 1, mdl + 1, right, a, b);
		
		if (len[maxv] < len[nv]) {
			maxv = nv;	
		}	
	}
	
	return maxv;
}

void update (int node, int left, int right, int value, int pos)
{	
	if (left == right) {
		arb[node] = value;
		return;
	}
	
	int mdl = left + ((right - left) >> 1);
	
	if (pos <= mdl) {
		update(node << 1, left, mdl, value, pos);	
	}
	
	if (pos > mdl) {
		update((node << 1) + 1, mdl + 1, right, value, pos);
	}
	
	arb[node] = (len[arb[node << 1]] > len[arb[(node << 1) + 1]]) ? arb[node << 1] : arb[(node << 1) + 1]; 
}

int main()
{
	fin >> n;
	
	for (int i = 1; i <= n; ++i) {
		fin >> a[i];
		arb[i] = a[i];	
	}
	
	normalize ();
	
	int maxp = 1;
	for (int i = 2; i <= n; ++i) {
		int j = query(1, 1, nv, 1, b[i] - 1);
		len[i] = len[j] + 1;
		prev[i] = j;
		update (1, 1, nv, i, b[i]);
		
		if (len[maxp] < len[i]) {
			maxp = i;	
		}
	}
	
	
	
	for (int i = 0, j = maxp; j; j = prev[j], ++i) {
		arb[i] = a[j];
	}
	
	fout << len[maxp] << endl;
	for (int i = len[maxp] - 1; i >=0; --i) {
		fout << arb[i] << " ";
	}
	fout << endl;
	
	fin.close();
	fout.close();
	return 0;   
}