Cod sursa(job #473175)

Utilizator dornescuvladVlad Eugen Dornescu dornescuvlad Data 28 iulie 2010 12:56:45
Problema Subsir crescator maximal Scor 35
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include <algorithm>

#include <cstdio>
#define nmax 100003
#define dim 8192

using namespace std;

char ax[dim];
int pz;

inline void cit (int &x)
{
	x = 0;
	while (ax[pz] < '0' || ax[pz] > '9')
		if (++pz == dim)
			fread (ax, 1, dim, stdin), pz = 0;

	while (ax[pz] >= '0' && ax[pz] <= '9')
	{
		x = x * 10 + ax[pz] - '0';
		if (++pz == dim)
			fread (ax, 1, dim, stdin), pz = 0;
	}
}

int N, i, j, k, dp[nmax], pred[nmax], rez, poz[262144], rasp[262144], 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()
{
	freopen ("scmax.in", "r", stdin);
	cit (N);
	//fin >> N;
	for(i = 1; i <= N; i ++)
	{
		cit (A[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 = j;
	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];
	
	freopen ("scmax.out", "w", stdout);

	printf ("%d\n", max2);
	//fout << max2;
	return 0;
}