Cod sursa(job #2522012)

Utilizator AlexNeaguAlexandru AlexNeagu Data 11 ianuarie 2020 20:34:52
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
ifstream in("scmax.in");
ofstream out("scmax.out");
vector < int > dp(N, 0), AIB(N * 2, -1);
int n;
int q(int pos) {
	int bst = -1, ans = -1;
	for (; pos; pos -= pos & (-pos)) {
		if (AIB[pos] == -1) {
			continue;
		}
		if (bst < dp[AIB[pos]]) {
			bst = dp[AIB[pos]];
			ans = AIB[pos];
		}
	}
	return ans;
}
void update(int pos, int ind) {
	for (; pos <= n; pos += pos & (-pos)) {
		if (AIB[pos] == -1 || dp[ind] > dp[AIB[pos]]) {
			AIB[pos] = ind;
		}
	}
}
int main() {
	in >> n;
	vector < int > v(n), ind(n), p(n), init(n);
	iota(p.begin(), p.end(), 0);
	for (int i = 0; i < n; i++) {
		in >> v[i];
		ind[i] = init[i] = v[i];
	}
	sort(ind.begin(), ind.end());
	auto it = unique(ind.begin(), ind.end());
	ind.resize(distance(ind.begin(), it));
	for (int i = 0; i < n; i++) {
		v[i] = lower_bound(ind.begin(), ind.end(), v[i]) - ind.begin();
		v[i] = v[i] + 1;
	}
	for (int i = 0; i < n; i++) {
		int bst_pos = q(v[i] - 1);
		if (bst_pos == -1) {
			dp[i] = 1;
			update(v[i], i);
		}
		else {
			p[i] = bst_pos;
			dp[i] = dp[bst_pos] + 1;
			update(v[i], i);
		}
	}
	int bst = 0, st;
	for (int i = 0; i < n; i++) {
		if (dp[i] > bst) {
				bst = dp[i];
				st = i;
		}
	}
	vector < int > ans;
	while(dp[st] != 1) {
		ans.push_back(st);
		st = p[st];
	}
	ans.push_back(st);
	out << bst << "\n";
	for (int i = bst - 1; i >= 0; i--) {
		out << init[ans[i]] << " ";
	}
	return 0;
}