Cod sursa(job #473145)

Utilizator dornescuvladVlad Eugen Dornescu dornescuvlad Data 28 iulie 2010 12:00:17
Problema Subsir crescator maximal Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <iostream>
#include <fstream>
#define nmax 100006

using namespace std;

const char iname[] = "scmax.in";
const char oname[] = "scmax.out";

ifstream fin(iname);
ofstream fout(oname);

int N, i, j, k, dp[nmax], pred[nmax], rez, poz[nmax * 3], rasp[nmax * 3], maxim, max2, A[nmax];
int position, max3;

void update(int nod, int left, int right, int valoare, int pozitie)
{
	if(left == right)
	{
		rasp[nod] = dp[pozitie];
		poz[nod] = pozitie;
		return;
	}
	else
	{
		int middle = (left + right) >> 1;
		if(valoare <= middle)
			update(2 * nod, left, middle, valoare, pozitie);
		else
			update(2 * nod + 1, middle + 1, right, valoare, pozitie);
	}
	rasp[nod] = max(rasp[2 * nod + 1], rasp[2 * nod]);
	if(rasp[2 * nod + 1] == rasp[nod])
		poz[nod] = poz[2 * nod + 1];
	else
		poz[nod] = poz[2 * nod];
	
}

void query(int nod, int left, int right, int lm, int rm)
{
	if(lm <= left && right <= rm)
	{
		if(rasp[nod] >= max2)
		{
			max2 = rasp[nod];
			max3 = poz[nod];
			return;
		}
		else
			return;
	}
	
	int middle = (left + right) >> 1;
	if(lm <= middle)
		query(2 * nod, left, middle, lm, rm);
	if(middle < rm)
		 query(2 * nod + 1, middle +1 , right, lm, rm);
}
		
	
int main()
{
	fin >> N;
	for(i = 1; i <= N; i ++)
	{
		fin >> A[i];
		if(A[i] > maxim)
			maxim = A[i];
	}
	
	dp[1] = 1;
	pred[1] = 1;
	update(1, 1, maxim, A[1], 1);
	for(i = 2; i <= N; i ++)
	{	
		max2 = 0;
		query(1, 1, maxim, 1, A[i] - 1);
		dp[i] = max(dp[i], dp[max3] + 1);
		update(1, 1, maxim, A[i], i);
	}
	
	max2 = 0;
	for(i = 1; i <= N; i ++)
		if(dp[i] > max2)
			max2 = dp[i];
	fout << max2;
	return 0;
}