Cod sursa(job #2952106)

Utilizator IanisBelu Ianis Ianis Data 8 decembrie 2022 11:58:49
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.1 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <bitset>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>

using namespace std;

#ifdef LOCAL
ifstream fin("input.txt");
#define fout cout
#else
ifstream fin("scmax.in");
ofstream fout("scmax.out");
#endif

#define lsb(x) (x & (-x))

const int NMAX = 1e5+5;

struct Node {
	int val, idx;
};

int n;
int a[NMAX];
Node dp[NMAX];
Node aint[4 * NMAX];
int ans[NMAX];
int b[NMAX];

void update(int node, int l, int r, int pos, int val, int idx) {
	if (l >= r) {
		aint[node] = {val, idx};
		return;
	}

	int mid = (l + r) / 2;
	
	if (pos <= mid)
		update(node * 2, l, mid, pos, val, idx);
	else
		update(node * 2 + 1, mid + 1, r, pos, val, idx);

	aint[node] = aint[node * 2].val > aint[node * 2 + 1].val ? aint[node * 2] : aint[node * 2 + 1];
}

Node query(int node, int l, int r, int lq, int rq) {
	if (lq <= l && r <= rq) {
		return aint[node];
	}

	int mid = (l + r) / 2;
	Node lnode = {}, rnode = {};

	if (lq <= mid)
		lnode = query(node * 2, l, mid, lq, rq);
	if (mid < rq)
		rnode = query(node * 2 + 1, mid + 1, r, lq, rq);

	return lnode.val > rnode.val ? lnode : rnode;
}

void read() {
	fin >> n;
	for (int i = 1; i <= n; i++)
		fin >> a[i];
}

void normalize(int src[], int dest[]) {
	vector<pair<int, int>> temp(n);
	for (int i = 0; i < n; i++)
		temp[i] = {src[i + 1], i + 1};
	sort(temp.begin(), temp.end());

	int val = 1;
	dest[temp[0].second] = 1;
	for (int i = 1; i < n; i++) {
		if (temp[i - 1].first != temp[i].first)
			val++;
		dest[temp[i].second] = val;
	}
}

void build_ans(int index) {
	if (index > 0) {
		ans[dp[index].val] = a[index];
		build_ans(dp[index].idx);
	}
}

void solve() {
	normalize(a, b);
	int mx = 0, mx_idx;
	for (int i = 1; i <= n; i++) {
		dp[i] = query(1, 1, NMAX - 1, 1, b[i]);
		dp[i].val++;
		update(1, 1, NMAX - 1, b[i] + 1, dp[i].val, i);
		if (dp[i].val > mx)
			mx = dp[i].val, mx_idx = i;
			
	}
	build_ans(mx_idx);
	fout << mx << '\n';
	for (int i = 1; i <= mx; i++)
		fout << ans[i] << ' ';
}

int32_t main() {
	read();
	solve();
	return 0;
}