Cod sursa(job #2660804)

Utilizator IRadu1529Radu Ionescu IRadu1529 Data 20 octombrie 2020 15:58:42
Problema Subsir crescator maximal Scor 35
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
typedef long long ll;
const int NMAX = 100001;
int  n, m, ma, aint[4 * NMAX], a[NMAX], vals[NMAX], d[NMAX], sol[NMAX];
struct nod {
	int copie, val;
};
vector<int> b;
vector<vector<nod> >noduri(NMAX, vector<nod>());
void update(int nod, int l, int r, int poz, int val) {
	if (l == r) {
		aint[nod] = val;
		return;
	}
	int mj = (l + r) / 2;
	if (poz > mj)
		update(nod * 2 + 1, mj + 1, r, poz, val);
	else
		update(nod * 2, l, mj, poz, val);
	aint[nod] = max(aint[nod * 2], aint[nod * 2 + 1]);
}
int query(int nod, int l, int r, int x, int y) {
	if (l >= x && r <= y) {
		return aint[nod];
	}
	int mj = (l + r) / 2;
	int s1 = 0, s2 = 0;
	if (x <= mj)
		s1 = query(nod * 2, l, mj, x, y);
	if (y > mj)
		s2 = query(nod * 2 + 1, mj + 1, r, x, y);
	return max(s1, s2);

}
int partition(int line, int low, int high) {
	nod pivot = noduri[line][high];
	int i = (low - 1);
	for (int j = low; j <= high - 1; j++) {
		if (noduri[line][j].val < pivot.val) {
			i++;
			swap(noduri[line][i], noduri[line][j]);
		}
	}
	swap(noduri[i + 1], noduri[high]);
	return (i + 1);
}
void quickSort(int line, int low, int high) {
	if (low < high) {
		int pi = partition(line, low, high);
		quickSort(line, low, pi - 1);
		quickSort(line, pi + 1, high);
	}
}
int main()
{
	fin >> n;
	for (int i = 1; i <= n; ++i) {
		fin >> a[i];
		vals[i] = a[i];
		b.push_back(a[i]);
	}
	sort(b.begin(), b.end());
	b.erase(unique(b.begin(), b.end()), b.end());
	for (int i = 1; i <= n; ++i)
		a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
	for (int i = 1; i <= n; ++i) {
		if (a[i] - 1 >= 1)
			ma = query(1, 1, n, 1, a[i] - 1);
		else ma = 0;
		d[i] = ma + 1;
		nod add;  add.copie = vals[i]; add.val = a[i];
		noduri[ma + 1].push_back(add);
		update(1, 1, n, a[i], d[i]);
	}
	int el, poz;
	for (int i = 1; i <= n; ++i)
		if (ma < d[i]) {
			el = a[i];
			poz = i;
			ma = d[i];
		}
	fout << ma << "\n";
	vector<int> res;
	res.push_back(vals[poz]);
	while (ma > 1) {
		for (int i = 0; i < noduri[ma - 1].size(); ++i) {
			if (noduri[ma - 1][i].val < el)
				poz = i;
			else
				break;
		}
		res.push_back(noduri[ma - 1][poz].copie);
		el = noduri[ma - 1][poz].val;
		ma--;
	}
	for (int i = res.size() - 1; i >= 0; --i)
		fout << res[i] << " ";
}