Cod sursa(job #1777777)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 12 octombrie 2016 21:15:42
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.7 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define INF 2000000000
#define MaxN 100005
#define MaxT 265000
using namespace std;
    
FILE *IN,*OUT;
int N,Orig[MaxN],v[MaxN],Max=0,Pos,X,Val,S=0,MaxPos,Prev,Pre[MaxN],pos,K[MaxN];
struct _Norm
{
	int val,pos;
}p[MaxN];
struct _Tree
{
	int val,pos;
}T[MaxT];
bool cond(_Norm a,_Norm b)
{
	return a.val<b.val;
}

inline void Update(int node,int start,int end)
{
	int mid;
	while(start!=end)
	{
		mid=(start+end)>>1;
		if(Pos>mid)start=mid+1,node=(node<<1)+1;
		else end=mid,node<<=1;
	}
	T[node].val=X;
	T[node].pos=pos;
	node>>=1;
	while(node)
	{
		T[node]=T[node<<1];
		if(T[node].val<T[1+(node<<1)].val)
			T[node]=T[1+(node<<1)];
		node>>=1;
	}
}
void Query(int node,int start,int end)
{
	if(Pos==1)
		return;
	else if(end<Pos)
	{
		if(Val<=T[node].val)
		{
			Val=T[node].val;
			if(v[Prev]<v[T[node].pos])Prev=T[node].pos;
		}
	}
	else
	{
		int mid=(start+end)>>1;
		Query(node<<1,start,mid);
		if(Pos-1>mid)Query((node<<1)+1,mid+1,end);
	}
}
int main()
{
	IN=fopen("scmax.in","r");
	OUT=fopen("scmax.out","w");
	
	fscanf(IN,"%d",&N);
	for(int i=1;i<=N;i++)
		fscanf(IN,"%d",&v[i]),p[i].pos=i,p[i].val=v[i],Orig[i]=v[i];
	sort(p+1,p+1+N,cond);
	for(int i=1;i<=N;i++)
	{
		if(p[i-1].val!=p[i].val)S++;
		v[p[i].pos]=S;
	}
	for(int i=1;i<=N;i++)
	{
		Pos=v[i];
		Val=0,Prev=0,pos=i;
		Query(1,1,N);
		X=1+Val;
		if(X==1)Prev=0;
		Pre[i]=Prev;
		if(Max<X)
			Max=X,MaxPos=i;
		Update(1,1,N);
	}
	fprintf(OUT,"%d\n",Max);
	S=Max;
	while(MaxPos)
	{
		K[S--]=Orig[MaxPos];
		MaxPos=Pre[MaxPos];
	}
	for(int i=1;i<=Max;i++)
		fprintf(OUT,"%d ",K[i]);
	return 0;
}