Cod sursa(job #1245789)

Utilizator radudorosRadu Doros radudoros Data 19 octombrie 2014 23:28:45
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.65 kb
#include <fstream>
#include <stack>
#include <chrono>
using namespace std;


#define nmax 100001


int t[nmax];
int LSC[nmax];
int v[nmax];
int aux_idx[nmax];
int vor[nmax];

ifstream fin("scmax.in");
ofstream fout("scmax.out");

int max2(int x, int y){ if (x >= y)  return x; else return y; }

int aib_max(int n)
{
	if (n - (n&(n - 1) ^ n) == 0)
		return t[n];
	return max2(aib_max(n - (n&(n - 1) ^ n)), t[n]);
}

void update(int x, int poz)
{
	int aux = aib_max(x - 1) + 1;
	LSC[poz] = aux;
	for (; x <= nmax - 1; x += x&(x - 1) ^ x)
	{

		if (t[x] < aux)
		{
			t[x] = aux;
		}
		else break;
	}
}

/*Functii de sortare*/
int partition(int i, int s, int v[], int aux_idx[])
{
	int l = i - 1;
	for (int j = i; j <= s; j++)
	if (v[j] <= v[s])
	{
		l++;
		int aux = v[j];
		int aux2 = aux_idx[j];
		v[j] = v[l];
		aux_idx[j] = aux_idx[l];
		v[l] = aux;
		aux_idx[l] = aux2;
	}
	return l;
}

void quicksort(int l, int r, int v[], int aux_idx[])
{
	if (r - l < 1)
		return;
	if (r - l == 1)
	{
		if (v[l]>v[r])
		{
			int aux = v[l];
			int aux2 = aux_idx[l];
			v[l] = v[r];
			aux_idx[l] = aux_idx[r];
			v[r] = aux;
			aux_idx[r] = aux2;
		}
		return;
	}

	int k = v[rand() % (r - l + 1) + l];
	int i = l;
	int j = r;
	while (i <= j)
	{
		while (v[i] < k)i++;
		while (v[j] > k)j--;
		if (i <= j)
		{
			int aux = v[i];
			int aux2 = aux_idx[i];
			v[i] = v[j];
			aux_idx[i] = aux_idx[j];
			v[j] = aux;
			aux_idx[j] = aux2;
			i++;
			j--;
		}
	}

	quicksort(l, i - 1, v, aux_idx);
	quicksort(i, r, v, aux_idx);
}
/*Functii sortare terminare*/

int main()
{

	chrono::steady_clock::time_point t1 = chrono::steady_clock::now();

	stack<int> q;
	srand(6782);
	int n;
	fin >> n;
	for (int i = 1; i <= n; i++)
	{
		fin >> v[i];
		vor[i] = v[i];
		aux_idx[i] = i;

	}
	quicksort(1, n, v, aux_idx);
	int aux3 = v[1];
	v[1] = 1;
	int j = 2;
	for (int i = 2; i <= n; i++)
	{
		if (v[i] == aux3)
			v[i] = v[i - 1];
		else
		{
			aux3 = v[i];
			v[i] = j;
			j++;
		}
	}
	quicksort(1, n, aux_idx, v);

	for (int i = 1; i <= n; i++)
	{
		update(v[i], i);/*treubie facut ulterior sortarii*/
	}


	int aux = aib_max(nmax);
	fout << aux << '\n';

	int aux2 = 100000;
	for (int i = n; i >= 1; i--)
	{
		if (LSC[i] == aux && v[i] < aux2)
		{
			q.push(vor[i]);
			aux2 = vor[i];
			aux--;
		}
	}

	while (!q.empty())
	{
		fout << q.top() << ' ';
		q.pop();
	}

	chrono::steady_clock::time_point t2=chrono::steady_clock::now();
	chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
/*	fout << time_span.count();*/
}