Cod sursa(job #552921)

Utilizator skullLepadat Mihai-Alexandru skull Data 13 martie 2011 10:29:52
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <stdio.h>
using namespace std;
#define nmax 100005

int SOL[nmax], poz[nmax], V[nmax];
int N, pozitie, maxim;

struct punct { int best, valoarea, pozitia; } arb[4*nmax];

void citire ()
{
	int i;
	scanf("%d", &N);
	for (i = 1; i <= N; ++i) scanf("%d", &V[i]);
}

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, punct 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 (arb[2*ind].best > arb[2*ind+1].best) arb[ind] = arb[2*ind];
		else arb[ind] = arb[2*ind+1];
}

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

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

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