Cod sursa(job #202720)

Utilizator nusmaibunkeleviprofesor cicalescu nusmaibunkelevi Data 10 august 2008 18:35:09
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include<stdio.h>
#include<stdlib.h>

#define NMAX 100000

long n,a[NMAX+1],b[NMAX+1],m;
int l[NMAX+1],maxim;
int best[NMAX*3];

int fcmp(const void*xx,const void*yy){
if ((*(long*)xx)>(*(long*)yy)) return 1;
else if ((*(long*)xx)<(*(long*)yy)) return -1;
	 else return 0;
}

int cauta(long x){
int i=1,j=m,mij;
while(i<=j){
	mij=(i+j)/2;
	if(b[mij]==x) return mij;
	else if(x<b[mij]) j=mij-1;
		 else i=mij+1;
	}
return 0;
}

void upd(int nod){
int i=1,j=m,k=1,mij,st,dr;
while(i<=j){
	if(i==j){
		best[k]=nod;
		k/=2;
		while(k){
			st=best[2*k];dr=best[2*k+1];
			if(l[st]>l[dr]) best[k]=st;
			else best[k]=dr;
			k/=2;
			}
		return;
		}
	else{
		mij=(i+j)/2;
		if(nod<=mij) {k=2*k;j=mij;}
		else {k=2*k+1;i=mij+1;}
		}
	}
}

void qry(int nod,int st,int dr,int li,int &mx){
int mij,mxst,mxdr;
mx=0;
if(li<=st&&dr<=m){
	if(mx<best[nod]) mx=best[nod];
	}
else{
	mij=(st+dr)/2;
	if(li<=mij) {qry(nod*2,st,mij,li,mxst);
	if(l[mx]<l[mxst]) mx=mxst; }
	if(dr<=m) {qry(nod*2+1,mij+1,dr,li,mxdr);
	if(l[mx]<l[mxdr]) mx=mxdr;}
	}
}

int main(){
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
int i,poz,lmax,first,next[NMAX+1]={0};
char sir[NMAX*11],*p;
scanf("%ld\n",&n);
fgets(sir,NMAX*10,stdin);p=sir;
for(i=1;i<=n;i++){
	a[i]=(long)atoi(p);
	while(*p!=32) p++;p++;
	b[i]=a[i];
	}
qsort(b,n+1,sizeof(b[0]),fcmp);
m=0;
for(i=1;i<=n;i++)
	if(b[i]!=b[i-1]) {m++;b[m]=b[i];}
for(i=n;i>0;i--){
	poz=cauta(a[i]);
	if(b[poz]<best[1])
		maxim=best[1];
	else {maxim=0;
	qry(1,1,m,poz+1,maxim);
	}
	l[poz]=l[maxim]+1;
	next[poz]=maxim;
	upd(poz);
	}
lmax=0;first=0;
for(i=1;i<=m;i++)
	if(l[i]>lmax) {lmax=l[i];first=i;}
printf("%d\n",lmax);
i=first;
while(next[i]!=0){
	printf("%ld ",b[i]);
	i=next[i];
	}
printf("%ld",b[i]);
return 0;
}