Cod sursa(job #218655)

Utilizator plastikDan George Filimon plastik Data 2 noiembrie 2008 21:33:45
Problema Subsir crescator maximal Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

const int NMAX = 100000;
const int TMAX = 1 << 18;
const int MINF = 0;

int Tree[TMAX], Id[NMAX], A[NMAX], ans = 0, n;

vector<pair<int, int> > Manip;

inline int left(int i) {
	return 2 * i;
}
inline int right(int i) {
	return 2 * i + 1;
}

void buildTree(int i, int l, int r) {
	if (l == r) {
		Tree[i] = MINF;
		return;
	}
	
	int m = (r - l) / 2 + l;
	buildTree(left(i), l, m);
	buildTree(right(i), m + 1, r);
	
	Tree[i] = max(Tree[left(i)], Tree[right(i)]);
}

int queryTree(int lt, int rt, int i, int l, int r) {
	if (lt <= l && r <= rt)
		return Tree[i];
	
	int m = (r - l) / 2 + l, ansl = MINF, ansr = MINF;
	if (lt <= m)
		ansl = queryTree(lt, rt, left(i), l, m);
	if (m < rt)
		ansr = queryTree(lt, rt, right(i), m + 1, r);
	
	return max(ansl, ansr);
}

void updateTree(const int pos, int i, int l, int r) {
	int q;
	if (l == r && l == Id[pos]) {
		if (Id[pos] > 1)
			q = queryTree(1, Id[pos] - 1, 1, 1, n);
		else
			q = 0;
		Tree[i] = max(q + 1, 1);
		
		ans = max(ans, Tree[i]);
		return;
	}
	
	int m = (r - l) / 2 + l;
	if (Id[pos] <= m)
		updateTree(pos, left(i), l, m);
	else
		updateTree(pos, right(i), m + 1, r);
	
	Tree[i] = max(Tree[left(i)], Tree[right(i)]);
}

int main() {
	
	freopen("scmax.in", "r", stdin);
	freopen("scmax.out", "w", stdout);
	
	scanf("%d", &n);
	int i;
	for (i = 0; i < n; ++ i) {
		scanf("%d ", &A[i]);
		Manip.push_back(make_pair(A[i], i));
	}
	
	sort(Manip.begin(), Manip.end());
	
	int id = 1;
	for (i = 0; i < n; ) {
		do {
			Id[Manip[i].second] = id;
			++ i;
		} while (i < n && Manip[i].first == Manip[i - 1].first);
		++ id;
	}
	
	buildTree(1, 1, n);
	for (i = 0; i < n; ++ i)
		updateTree(i, 1, 1, n);
	
	printf("%d\n", ans);
	
	return 0;
}