Cod sursa(job #553474)

Utilizator skullLepadat Mihai-Alexandru skull Data 14 martie 2011 08:56:07
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <stdio.h>
#include <algorithm>
using namespace std;
#define nmax 100005

int arb[4*nmax], SOL[nmax], poz[nmax], V[nmax], ord[nmax], pz[nmax];
int N, pozitie, maxim;

struct cmp
{
	bool operator () (const int &a, const int &b) const
	{
		return V[a] < V[b];
	}
};

void citire ()
{
	int i, h;
	scanf("%d", &N);
	for (i = 1; i <= N; ++i) { scanf("%d", &V[i]); ord[i] = V[i]; }
	sort(ord+1, ord+N+1);
	h = 1;
	for (i = 2; i <= N; ++i)
		if (ord[i] != ord[h])
			ord[++h] = ord[i];
	for (i = 1; i <= N; ++i)
		pz[i] = lower_bound(ord+1, ord+h+1, V[i])-ord;

}

void afisare (int x)
{
	if ( x ) afisare(poz[x]);
		else return;
	printf("%d ", V[x]);
}

void update(int ind, int st, int dr, int indx, int x)
{
	if (st == dr) { arb[ind] = x; return; }
	int mij = (st+dr) / 2;
	if (indx <= mij) update(2*ind, st, mij, indx, x);
		else update(2*ind+1, mij+1, dr, indx, x);
	if (SOL[arb[2*ind]] > SOL[arb[2*ind+1]]) arb[ind] = arb[2*ind];
		else arb[ind] = arb[2*ind+1];
}

void query(int ind, int st, int dr, int a, int b)
{
	if (a <= st && dr <= b)
	{
		if (SOL[arb[ind]] > maxim) { maxim = SOL[arb[ind]]; pozitie = arb[ind]; }
		return ; 
	}
	int mij = (st+dr) / 2;
	if (a <= mij) query(2*ind, st, mij, a, b);
	if (mij < b) query(2*ind+1, mij+1, dr, a, b);
}

void solve ()
{
	int i, ind, rez = 0;
	SOL[1] = 1;
	update(1, 1, N, pz[1], 1);
	for (i = 2; i <= N; ++i)
	{
		maxim = 0; pozitie = 0;
		if (pz[i] == 1) { maxim = 0; pozitie = 0; }
			else query(1, 1, N, 1, pz[i]-1);
		SOL[i] = maxim + 1; poz[i] = pozitie;
		if (SOL[i] > rez) { rez = SOL[i]; ind = i; }
		update(1, 1, N, pz[i], i); 
	}
	printf("%d\n", SOL[ind]);
	afisare (ind);
}

int main ()
{
	freopen("scmax.in","r",stdin);
	freopen("scmax.out","w",stdout);
	citire ();
	solve ();
	return 0;
}