Cod sursa(job #471312)

Utilizator vlad.maneaVlad Manea vlad.manea Data 18 iulie 2010 02:27:01
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.42 kb
#include <fstream>
#include <vector>
#include <map>

using namespace std;

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

map<unsigned, unsigned> M;
vector<unsigned> E;
vector<unsigned> P;

class Tree {

private:
	
	vector< pair<unsigned, unsigned > > _t;
	int N;

	void _update(unsigned n, unsigned v, unsigned l, unsigned r, unsigned i, unsigned k) {

		if (l > r) {
			return;
		} else if (v <= l) {
			_t[n] = max(pair<unsigned, unsigned>(k, i), _t[n]);
		} else {
			unsigned m = (l + r) >> 1;
			if (v <= m) {
				_update(n << 1, v, l, m, i, k);
			} 
			if (1) {
				_update(n << 1 | 1, v, m + 1, r, i, k);
			}
		}

	}

	pair<int, int> max(pair<int, int> p1, pair<int, int> p2) {
		return (p1.first > p2.first? p1: p2);
	}

	pair<int, int> _query(unsigned n, unsigned v, unsigned l, unsigned r) {

		if (l > r) {
			return pair<int, int>(0, 0);
		} else if (v <= l || l == r) {
			return _t[n];
		} else {
			unsigned m = (l + r) >> 1;
			if (v <= m) {
				return max(_t[n], _query(n << 1, v, l, m));
			} else {
				return max(_t[n], _query(n << 1 | 1, v, m + 1, r));
			}
		}

	}

public:

	Tree(unsigned N) {

		_t.clear();
		this->N = N;
		N <<= 2;

		for (unsigned i = 0; i <= N; ++i) {
			_t.push_back(pair<unsigned, unsigned>(0, 0));
		}

	}

	void update(unsigned v, unsigned i, unsigned l) {
		_update(1, v, 1, N, i, l);
	}

	pair<unsigned, unsigned> query(unsigned v) {
		return _query(1, v, 1, N);
	}

};

void back(int p) {

	if (p > 0) {

		back(P[p]);
		fout << E[p] << ' ';
	
	}

}

int main() {

	unsigned N, i, l, v, k, maxe, pmax;
	map<unsigned, unsigned>::iterator j;
	pair<unsigned, unsigned> p;

	fin >> N;
	E.push_back(0);
	P.push_back(0);
	
	// populate structures
	for (i = 1, maxe = 0; i <= N; ++i) {
		fin >> v;
		E.push_back(v);
		P.push_back(0);
		M.insert(pair<unsigned, unsigned>(v, 0));
	}

	// create positions
	for (j = M.begin(), i = 1; j != M.end(); ++j, ++i) {
		j->second = i;
	}

	// create tree
	Tree t(i);

	// update
	for (l = 1; l <= N; ++l) {
		
		// get this position
		k = M.find(E[l])->second;

		// get pair
		p = t.query(k);

		// update this length
		t.update(k + 1, l, v = 1 + p.first);

		// get prev
		P[l] = t.query(k).second;

		if (v > maxe) {
			maxe = v;
			pmax = l;
		}

	}

	fout << maxe << '\n';

	back(pmax);

	fin.close();
	fout.close();

	return 0;
}