Cod sursa(job #2665187)

Utilizator IRadu1529Radu Ionescu IRadu1529 Data 30 octombrie 2020 12:21:57
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.13 kb
#include <fstream>
#include <algorithm>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
const int MaxN = 100001;

struct seg {
	seg() {
		d = src = 0;
	}
	int d, src;
};

seg tree[4 * MaxN];

int v[MaxN], ind[MaxN], k[MaxN], sol[MaxN], in[MaxN];

static inline int lSon(int node) {
	return (node << 1);
}

static inline int rSon(int node) {
	return (node << 1) + 1;
}

void update(int node, int st, int dr, int i, int val, int s) {
	int mij = (st + dr) / 2;
	if (st == dr) {
		tree[node].d = val;
		tree[node].src = s;
		return;
	}
	if (i <= mij) {
		update(lSon(node), st, mij, i, val, s);
	}
	else {
		update(rSon(node), mij + 1, dr, i, val, s);
	}
	if (tree[lSon(node)].d > tree[rSon(node)].d) {
		tree[node].d = tree[lSon(node)].d;
		tree[node].src = tree[lSon(node)].src;
	}
	else {
		tree[node].d = tree[rSon(node)].d;
		tree[node].src = tree[rSon(node)].src;
	}
}

int qi = 0;

seg query(int node, int st, int dr, int x, int y) {
	int mij = (st + dr) / 2;
	seg l, r;
	if (x <= st && dr <= y) {
		return tree[node];
	}
	if (x <= mij) {
		l = query(lSon(node), st, mij, x, y);
	}
	if (y > mij) {
		r = query(rSon(node), mij + 1, dr, x, y);
	}
	if (l.d > r.d) {
		qi = l.src;
		return l;
	}
	else {
		qi = r.src;
		return r;
	}
}

int cmp(int a, int b) {
	return v[a] < v[b];
}

int nrm[MaxN];

int main() {
	int n, i, j;
	int nr;
	fin >> n;
	for (i = 1; i <= n; ++i) {
		fin >> v[i];
		ind[i] = i;
	}
	sort(ind + 1, ind + n + 1, cmp);////sortare cu tot cu indici
	j = 0;
	for (i = 1; i <= n; ++i) {////partea de normalizare
		if (v[ind[i]] == v[ind[i - 1]]) {
			nrm[ind[i]] = j;
		}
		else {
			++j;
			nrm[ind[i]] = j;
		}
	}
	for (i = 1; i <= n; ++i) {
		qi = 0;
		if (nrm[i] != 1) {
			nr = query(1, 1, n, 1, nrm[i] - 1).d + 1;
		}
		else {
			nr = 1;
		}
		k[i] = qi;
		update(1, 1, n, nrm[i], nr, i);
	}
	fout << tree[1].d << "\n";
	i = tree[1].src;
	j = 0;
	while (i != 0) {
		sol[j++] = v[i];
		i = k[i];
	}
	for (i = tree[1].d - 1; i >= 0; --i) {
		fout << sol[i] << " ";
	}
	fin.close();
	fout.close();
	return 0;
}