Cod sursa(job #641579)

Utilizator andra23Laura Draghici andra23 Data 28 noiembrie 2011 21:36:58
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include<iostream>
#include<fstream>
#include<algorithm>

using namespace std;

const int MAXN = 100010;
const int MAXNT = 300010;
int longest[MAXN], parent[MAXN], tree[MAXNT], v[MAXN];
pair <int,int> a[MAXN];

int buildTree(int pos, int left, int right, int tree[]) {
	if (left == right) {
		tree[pos] = left;
		return left;
	}
	buildTree(2*pos, left, (left+right)/2, tree);
	buildTree(2*pos+1, (left+right)/2+1, right, tree);
	tree[pos] = tree[2*pos];
	return tree[pos];
}

int queryTree(int pos, int left, int right, int a, int b, int tree[], int v[]) {
	if (a <= left && right <= b) {
		return tree[pos];
	}
	int m = (left+right)/2;
	int posMaxLeft = -1, posMaxRight = -1;
	if (a <= m) {
		posMaxLeft = queryTree(2*pos, left, m, a, b, tree, v);
	}
	if (b >= m+1) {
		posMaxRight = queryTree(2*pos+1, m+1, right, a, b, tree, v);
	}
	if (posMaxLeft == -1 || (posMaxRight > 0 && v[posMaxLeft] < v[posMaxRight])) {
		return posMaxRight;
	}
	return posMaxLeft;
}

int updateTree(int pos, int left, int right, int posVal, int tree[], int v[]) {
	if (left == right) {
		return tree[pos];
	}
	int m = (left+right)/2;
	int newMaxPos = -1;
	if (posVal <= m) {
		newMaxPos = updateTree(2*pos, left, m, posVal, tree, v);
	} else {
		newMaxPos = updateTree(2*pos+1, m+1, right, posVal, tree, v);
	}
	if (v[newMaxPos] > v[tree[pos]]) {
		tree[pos] = newMaxPos;
	}
	return tree[pos];
}

void printSubsequence(ofstream &g, int pos, int parent[], int v[]) {
	if (parent[pos]) {
		printSubsequence(g, parent[pos], parent, v);
	}
	g << v[pos] << " ";
}

int cmp (pair <int,int> a, pair <int,int> b) {
	return (a.first < b.first) || 
		(a.first == b.first && a.second > b.second);
}

int main() {
	ifstream f("scmax.in");
	ofstream g("scmax.out");
	int n;
	f >> n;

	for (int i = 1; i <= n; i++) {
		f >> v[i];
		a[i] = make_pair(v[i], i);
	}

	buildTree(1, 1, n, tree);
	sort(a+1, a+n+1, cmp);
	
	for (int i = 1; i <= n; i++) {
		int pos = a[i].second;
		int posMax = 0;
		if (pos > 1) { 
			posMax = queryTree(1, 1, n, 1, pos - 1, tree, longest);
		}
		longest[pos] = longest[posMax]+1;
		if (longest[pos] > 1) {
			parent[pos] = posMax;
		}
		updateTree(1, 1, n, pos, tree, longest);
	}

	int maxValue = 0;
	int posMax = 0;
	for (int i = 1; i <= n; i++) {
		if (longest[i] > maxValue) {
			maxValue = longest[i];
			posMax = i;
		}
	}

	g << maxValue << '\n';
	printSubsequence(g, posMax, parent, v);
	g << '\n';
	
	return 0;
}