Cod sursa(job #389886)

Utilizator Cristi09Cristi Cristi09 Data 2 februarie 2010 13:45:23
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.2 kb
#include<fstream.h>
#define MID int mid=(left+right)/2;
#define APOS arb[nod].pos
#define NMAX 100000
int a[NMAX+1],best[NMAX+1],poz[NMAX+1],n,pos,var;
struct arbore
{
	void init(int a,int b,int c)
	{
		val=a;
		pos=b;
		max=c;
	}
	int val, pos, max;
}arb[4*NMAX+1];
ofstream g("scmax.out");
void afis()
{
   int i=pos;
   do
   {
		g<<a[i]<<" ";
		i=poz[i];
   }while(i!=-1);

}
int max(int a,int b)
{
	if(a>=b)return a;
	return b;
}
void init(int nod,int left,int right)
{
   arb[nod].pos=left;
   if(left==right)
	{
	   if(left==n)arb[nod].init(1,n,a[n]);
	   return;
    }
   MID
   init(nod*2,left,mid);
   init(nod*2+1,mid+1,right);
   
   arb[nod].val=max(arb[nod*2].val,arb[nod*2+1].val);
   arb[nod].max=max(arb[nod*2].max,arb[nod*2+1].max);
   if(arb[nod].val==arb[nod*2].val)arb[nod].pos=arb[nod*2].pos;
   else arb[nod].pos=arb[nod*2+1].pos;
}
void update(int nod,int left,int right,int x,int pos)
{
	 if(left==right)
	 {
		arb[nod].init(max(arb[nod].val,x),left,a[left]);
		return;
	 }
	 MID
	 if(pos<=mid)update(nod*2,left,mid,x,pos);
	 else update(nod*2+1,mid+1,right,x,pos);

	 arb[nod].val=max(arb[nod*2].val,arb[nod*2+1].val);
	 arb[nod].max=max(arb[nod*2].max,arb[nod*2+1].max);
	 if(arb[nod].val==arb[nod*2].val)arb[nod].pos=arb[nod*2].pos;
	 else arb[nod].pos=arb[nod*2+1].pos;
}
void querry(int nod,int left,int right,int pos)
{
	if( best[pos]<arb[nod].val+1 && a[pos]<a[APOS] )
	{
		best[pos]=arb[nod].val+1;
		var=arb[nod].pos;
		poz[pos]=var;
		return;
	}
	if(left==right)return;
	MID
	if( best[pos]<arb[nod*2].val+1 && a[pos]<arb[nod*2].max)querry(nod*2,left,mid,pos);
	if( best[pos]<arb[nod*2+1].val+1 && a[pos]<arb[nod*2+1].max)querry(nod*2+1,mid+1,right,pos);
}
int dinamic()
{
	//update(1,1,n,best[n],n);
	int i,max=1;
	pos=n;
	for(i=n-1;i>0;--i)
	{
		best[i]=1;
		poz[i]=-1;
		var=-1;
		if(a[i]<arb[1].max)querry(1,1,n,i);
		if(var!=-1)
		{
			if(max<best[i]){max=best[i];pos=i;}
		}
		update(1,1,n,best[i],i);
	}
	return max;
}
int main()
{
    ifstream f("scmax.in");
    f>>n;
	int i;
	for(i=1;i<=n;++i)
    f>>a[i];
	f.close();
	best[n]=1;
	poz[n]=-1;
	init(1,1,n);
	g<<dinamic()<<"\n";
	afis();
	g.close();
}