Cod sursa(job #221467)

Utilizator Adriana_SAdriana Sperlea Adriana_S Data 16 noiembrie 2008 16:57:44
Problema Subsir crescator maximal Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <stdio.h>
#include <vector>
#include <algorithm>

#define mij (((st) + (dr)) / 2)
#define fiu1 ((nod) * 2)
#define fiu2 (((nod) * 2) + 1)

using namespace std;

const int N_MAX = 100010;
const int A_MAX = 1 << 18;

pair <int, int> v[N_MAX];
int aint[A_MAX], mxpoz[A_MAX], din[N_MAX], prec[N_MAX], vec[N_MAX], sol[N_MAX];
int rez, pz;

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

void update(int nod, int st, int dr, int poz, int val)
{
	if (st == dr) {
		aint[nod] = val;
		mxpoz[nod] = st;
	}
	else {
		if (poz <= mij) update(fiu1, st, mij, poz, val);
		if (poz > mij) update(fiu2, mij + 1, dr, poz, val);
		if (aint[fiu1] > aint[fiu2]) {
			aint[nod] = aint[fiu1];
			mxpoz[nod] = mxpoz[fiu1];
		} else {
			aint[nod] = aint[fiu2];
			mxpoz[nod] = mxpoz[fiu2];
		}
	}
}

void query(int nod, int st, int dr, int a, int b)
{
	if (a <= st && dr <= b) {
		if (aint[nod] > rez) {
			rez = aint[nod];
			pz = mxpoz[nod];
		}
	} else {
		if (a <= mij) query(fiu1, st, mij, a, b);
		if (b > mij) query(fiu2, mij + 1, dr, a, b);
	}
}

int main()
{
	freopen("scmax.in", "r", stdin);
#ifndef _SCREEN_
	freopen("scmax.out", "w", stdout);
#endif

	int N, x;
	scanf("%d\n", &N);
	for (int i = 1; i <= N; i ++) {
		scanf("%d ", &x);
		vec[i] = x;
		v[i] = make_pair(x, i); 
	}

	sort(v + 1, v + N + 1);
	din[v[1].second] = 1;
	prec[v[1].second] = 0;
	update(1, 1, N, v[1].second, 1);

	for (int i = 2; i <= N; i ++) {
		if (v[i].first != v[i - 1].first) {
			rez = 0, pz = 0;
			if (v[i].second - 1 >= 1) query(1, 1, N, 1, v[i].second - 1);
			else rez = 0, pz = 0;
			din[v[i].second] = rez + 1;
			prec[v[i].second] = pz;
		   	update(1, 1, N, v[i].second, din[v[i].second]);
		}
	}

	int fin = 0, ult = 0;
	for (int i = 1; i <= N; i ++) {
		if (din[i] > fin) {
			fin = din[i];
			ult = i;
		}
	}

	printf("%d\n", fin);
	while (ult != 0) {
		sol[++ sol[0]] = vec[ult];
		ult = prec[ult];
	}
	for (int i = sol[0]; i >= 1; i --) printf("%d ", sol[i]);
	printf("\n");

	return 0;
}