Cod sursa(job #473177)

Utilizator blasterzMircea Dima blasterz Data 28 iulie 2010 12:58:38
Problema Subsir crescator maximal Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.77 kb
#include <algorithm>

#include <cstdio>
#include <cstring>
#define nmax 100006
#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;
	}
}


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

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

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

nod b[nmax];

void rad (int n,int byte, nod a[], nod b[])
{
	int ind[256], cnt[256];
	memset (cnt, 0, sizeof (cnt));

	int i;

	for (i = 1; i <= n; ++i)
		++cnt[(a[i].v >> byte) & 255];

	ind[0] = 1;

	for (i = 1; i < 256; ++i)
		ind[i] = ind[i - 1] + cnt[i - 1];

	for (i = 1; i <= n; ++i)
		b[ind[(a[i].v >> byte) & 255]++] = a[i];
}

inline void radix (int n, nod a[])
{
	rad (n, 0, a, b);
	rad (n, 8, b, a);
	rad (n, 16, a, b);
	rad (n, 24, b, a);
}



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());

	radix (N, aux);
	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];
	
	freopen ("scmax.out", "w", stdout);

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