Cod sursa(job #3241987)

Utilizator EricDimiericdc EricDimi Data 6 septembrie 2024 23:21:06
Problema Subsir crescator maximal Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.16 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 stanga a.i. best[dr] > x
	int st = 1, dr = maxLen, mij, ans = maxLen;
	while (st <= dr)
	{
		mij = (st + dr) >> 1;
		if (best[mij] > x)
		{
			dr = mij - 1;
			ans = min(ans, mij);
		}
		else
			st = mij + 1;
	}
	return ans;
}

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;
}