Mai intai trebuie sa te autentifici.

Cod sursa(job #344138)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 28 august 2009 17:16:22
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.05 kb
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define N (1<<17)
#define P (1<<18)
using namespace std;
int n,v[N],nr[N],sortat[N],r;
int sol[N],x,poz;
int arb[P],best[N],inc,sf,maxim,rez,poz_f;
char line[N*11];
int u;
inline int digit(char x)
{
	return '0' <= x && x <= '9';
}
void read()
{
	scanf("%d\n",&n);
	int i,c=1;
	fgets(line+1, N*11, stdin);
	for (i=1; i<=n; i++)
	{
		while (!digit(line[c])) ++c;
		while (digit(line[c]))
		{
			v[i] = v[i]*10 + line[c] - '0';
			++c;
		}
	}
}
int cbin(int x)
{
	int i,step;
	for (step=1; step<=r; step<<=1);
	for (i=0; step; step>>=1)
		if (i+step<=r && sortat[i+step]<=x)
			i+=step;
	return i;
}
void renumerotare()
{
	memcpy(nr,v,sizeof(v));
	sort(nr+1,nr+n+1);
	int i,t;
	for (i=1; i<=n; i++)
		if (nr[i]!=nr[i-1])
			sortat[++r]=nr[i];
	for (i=1; i<=n; i++)
	{
		t=cbin(v[i]);
		v[i]=t;
	}
}
inline int maximum(int a,int b)
{
	if (a>b)
		return a;
	return b;
}
void update(int nod,int st,int dr)
{
	if (st==dr)
	{
		arb[nod]=maximum(x,arb[nod]);
		return;
	}
	int t=(st+dr)/2;
	if (poz<=t)
		update(nod*2,st,t);
	else
		update(nod*2+1,t+1,dr);
	arb[nod]=maximum(arb[nod*2],arb[nod*2+1]);
}
void query(int nod,int st,int dr)
{
	if (inc<=st && dr<=sf)
	{
		if (maxim<arb[nod])
			maxim=arb[nod];
		return;
	}
	int t=(st+dr)/2;
	if (inc<=t)
		query(nod*2,st,t);
	if (t<sf)
		query(nod*2+1,t+1,dr);
}
void solve()
{
	int i;
	for (i=1; i<=n; i++)
	{
		maxim=0;
		inc=1;
		sf=v[i]-1;
		if (sf)
			query(1,1,r);
		best[i]=maxim+1;
		if (best[i]>rez)
		{
			rez=best[i];
			poz_f=i;
		}
		x=best[i];
		poz=v[i];
		update(1,1,r);
	}
	printf("%d\n",rez);
}
void show()
{
	int i;
	while (rez)
	{
		sol[++u]=poz_f;
		for (i=poz_f-1; i>=1; i--)
			if (best[i]==rez-1)
			{
				poz_f=i;
				break;
			}
		rez--;
	}
	for (i=u; i>=1; i--)
		printf("%d ",sortat[v[sol[i]]]);
}
int main()
{
	freopen("scmax.in","r",stdin);
	freopen("scmax.out","w",stdout);
	read();
	renumerotare();
	solve();
	show();
	return 0;
}