Cod sursa(job #3142589)

Utilizator David8406Marian David David8406 Data 22 iulie 2023 16:59:32
Problema Subsir crescator maximal Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
	#include <iostream>
	#include <algorithm>
	#include <fstream>
	using namespace std;
	int n, v[100005], s[100005], dp[100005], aib[100005], prv[100005], aibprv[100005], vcopy[100005];
	ifstream fin("scmax.in");
	ofstream fout("scmax.out");
	int cautare_binara(int x) {
		int rez = 0;
		for (int i = 17; i >= 0; i--) {
			if ((rez + (1 << i)) <= n && s[rez + (1 << i)] < x) rez += (1 << i);
		}
		return rez+1;
	}
	void update(int poz, int val, int k) {
		while (poz <= n) {
			if (aib[poz] < val) {
				aib[poz] = val;
				aibprv[poz] = k;
			}
			poz += (poz & (poz ^ (poz - 1)));
		}
	}
	pair<int,int> query(int poz) {
		int rez = 0;
		int k = 0;
		while (poz > 0) {
			if (rez < aib[poz]) {
				rez = aib[poz];
				k = aibprv[poz];
			}
			poz -= (poz & (poz ^ (poz - 1)));
		}
		return {rez,k};
	}
	void reconstituire(int poz) {
		if (poz == 0) return;
		reconstituire(prv[poz]);
		cout << vcopy[poz] << " ";
	}
	int main() {
		fin >> n;
		for (int i = 1; i <= n; i++) {
			fin >> v[i];
			s[i] = v[i];
			vcopy[i] = v[i];
		}
		sort(s + 1, s + n + 1);
		for (int i = 1; i <= n; i++) {
			v[i] = cautare_binara(v[i]);
		}
		for (int i = 1; i <= n; i++) {
			pair<int, int> val = query(v[i] - 1);
			dp[i] = 1 + val.first;
			prv[i] = val.second;
			update(v[i],dp[i],i);
		}
		int mx = 0,poz;
		for (int i = 1; i <= n; i++) {
			if (mx < dp[i]) {
				mx = dp[i];
				poz = i;
			}
		}
		fout << mx << "\n";
		reconstituire(poz);
	}