Cod sursa(job #473156)

Utilizator blasterzMircea Dima blasterz Data 28 iulie 2010 12:40:18
Problema Subsir crescator maximal Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 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], B[nmax];
int position, max3, val;

struct nod { int v, poz;};nod aux[nmax];

struct cmp
{
	bool operator()(const nod &a, const nod &b)const
	{
		if(a.v < b.v)
			return 1;
		return 0;
	}
};



inline void update(int nod, int left, int right, int valoare, int pozitie)
{
	if(left == right)
	{
		rasp[nod] = dp[pozitie];
		poz[nod] = pozitie;
		return;
	}
	int middle = (left + right) >> 1;
	int L = nod << 1;
	int R = L | 1;

	if(valoare <= middle)
		update(L, left, middle, valoare, pozitie);
	else
			update(R, middle + 1, right, valoare, pozitie);
	rasp[nod] = max(rasp[R], rasp[L]);
	if(rasp[R] == rasp[nod])
		poz[nod] = poz[R];
	else
		poz[nod] = poz[L];
	
}

inline 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;
	}
	
	int middle = (left + right) >> 1;
	int L = nod << 1;
	int R = L | 1;

	if(lm <= middle)
		query(L, left, middle, lm, rm);
	if(middle < rm)
		 query(R, middle +1 , right, lm, rm);
}
		
	
int main()
{
	fin >> N;
	for(i = 1; i <= N; i ++)
	{
		fin >> A[i];
		aux[i].v = A[i];
		aux[i].poz = i;
		
	}
	
	dp[1] = 1;
	pred[1] = 1;
	j = 1;
	sort(aux + 1, aux + N + 1, cmp());
	B[aux[1].poz] = ++j;
	for(i = 2; i <= N; i ++)
	{
		if(aux[i].v != aux[i - 1].v)
			B[aux[i].poz] = ++j;
		else
			B[aux[i].poz] = j;
	}
	
	maxim = N;
	update(1, 1, maxim, B[1], 1);
	for(i = 2; i <= N; i ++)
	{	
		max2 = 0;
		query(1, 1, maxim, 1, B[i] - 1);
		dp[i] = max(dp[i], dp[max3] + 1);
		update(1, 1, maxim, B[i], i);
	}
	
	max2 = 0;
	for(i = 1; i <= N; i ++)
		if(dp[i] > max2)
			max2 = dp[i];
	fout << max2;
	return 0;
}