Cod sursa(job #3241986)

Utilizator EricDimiericdc EricDimi Data 6 septembrie 2024 23:16:17
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.12 kb
/// Solutie O(n log n)
#include <bits/stdc++.h>

using namespace std;

ifstream f("scmax.in");
ofstream g("scmax.out");

const int NMAX = 1e5;

int a[NMAX + 1];
int best[NMAX + 1]; /// best[i] = cel mai mic element din a[]
/// care poate fi plasat pe poz. i in scmax
int poz[NMAX + 1]; /// poz. pe care a fost plasata val. a[i]
/// in vectorul best[]
int sol[NMAX + 1];
int n, maxLen, idx;

int cb(int x)
{
	/// pozitia cea mai din dreapta a.i. best[dr] > x
	int st = 0, dr = maxLen + 1, mij;
	while (dr - st > 1)
	{
		mij = (st + dr) >> 1;
		if (best[mij] < x)
			st = mij;
		else
			dr = mij;
	}
	return dr;
}

int main()
{
	f >> n;
	for (int i = 1; i <= n; i++)
		f >> a[i];
	f.close();

	best[1] = a[1]; poz[1] = 1; maxLen = 1;

	for (int i = 2; i <= n; i++)
	{
		if (a[i] > best[maxLen])
		{
			best[++maxLen] = a[i];
			poz[i] = maxLen;
		}
		else
		{
			idx = cb(a[i]);
			best[idx] = a[i];
			poz[i] = idx;
		}
	}

	for (int j = n, i = maxLen; i >= 1; j--)
		if (poz[j] == i)
		{
			sol[i] = a[j];
			i--;
		}

	g << maxLen << '\n';
	for (int i = 1; i <= maxLen; i++)
		g << sol[i] << ' ';
	g << '\n';
	g.close();

	return 0;
}