Cod sursa(job #3194700)

Utilizator AndreiMLCChesauan Andrei AndreiMLC Data 18 ianuarie 2024 22:36:03
Problema Subsir crescator maximal Scor 35
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cmath>
#include <stack>
#include <set>
#include <map>

using namespace std;

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

const int nmax = 100005;
int n;
int v[nmax];
int best[nmax];
int pre[nmax];
int lung_max;
int start_poz;
int rez[nmax];

void scmax_slab()
{
	for (int i = n; i >= 1; i--) {
		best[i] = 1;
		pre[i] = -1;
		for (int j = i + 1; j <= n; j++) {
			if (v[j] > v[i]) {
				if (best[j] + 1 > best[i]) {
					best[i] = best[j] + 1;
					pre[i] = j;
				}
			}
		}
		if (best[i] > lung_max)
		{
			lung_max = best[i];
			start_poz = i;
		}
	}
}

void varianta_1_slab()
{
	scmax_slab();
	g << lung_max << '\n';
	bool last = 0;
	while (!last)
	{
		if (pre[start_poz] == -1)
		{
			last = 1;
		}
		g << v[start_poz] << ' ';
		start_poz = pre[start_poz];
	}
}

void afis(int indice)
{
	if (rez[indice] != -1)
	{
		afis(rez[indice]);
	}
	g << v[indice] << ' ';
}
void varianta_2()
{
	/*
	//Ciudat, nu merge cum ar trebui
	auto a = lower_bound(v + 1, v + 1 + n, 12);
	for (int i = 1; i <= n; i++)
	{
		g << v[i] << ' ';
	}
	g << '\n';
	g << *a;
	*/
	for (int i = 1; i <= n; i++)
	{
		rez[i] = -1;
	}
	best[1] = 1;
	lung_max = 1;
	int curent = 1;
	for (int i = 2; i <= n; i++)
	{
		if (v[i] > v[best[curent]])
		{
			rez[i] = best[curent];
			lung_max++;
			curent++;
			best[curent] = i;
			start_poz = i;
		}else if(v[i] < v[best[1]]) {
			best[1] = i;
		}
		else {
			int st=1,dr=curent,mij=(dr+st)/2;
			bool stop = 0;
			while (st<=dr && !stop)
			{
				if (v[best[mij]] < v[i] && v[best[mij + 1]] >= v[i])
				{
					stop = 1;
					st = mij;
				}
				if (v[best[mij]] > v[i])
				{
					dr = mij;
				}
				else {
					st = mij + 1;
				}
				mij = (st + dr) / 2;
			}
			best[st] = i;
		}
	}

	g << lung_max << '\n';
	afis(start_poz);
}

int main()
{
	f >> n;
	for (int i = 1; i <= n; i++)
	{
		f >> v[i];
	}
	//varianta_1_slab();
	varianta_2();
}