Cod sursa(job #1201390)

Utilizator tudi98Cozma Tudor tudi98 Data 25 iunie 2014 02:45:59
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <fstream>
#include <stack>
#include <iostream>
#include <algorithm>
#include <utility>
using namespace std;
#define dim 100005
#define mp make_pair
#define ff first
#define ss second

struct Tree{int Max,pos;};

stack<int> S;
pair<int,int> v[dim];
int i,pozA[dim],last[dim],d[dim],Pos,val;
Tree Arb[dim*4];


void update(int nod,int l,int r,int P){
	if(l==r){
		if(val > Arb[nod].Max) Arb[nod].Max=val,Arb[nod].pos=P;
		return;
	}
	int mid=(l+r)/2;
	if(Pos<=mid) update(nod*2,l,mid,P);
	if(Pos>mid) update(nod*2+1,mid+1,r,P);

	if(Arb[nod*2].Max > Arb[nod*2+1].Max){       //alegem fiul cu subsirul cel mai lung
		Arb[nod].Max=Arb[nod*2].Max;
		Arb[nod].pos=Arb[nod*2].pos;
	}
	else{
		Arb[nod].Max=Arb[nod*2+1].Max;
		Arb[nod].pos=Arb[nod*2+1].pos;
	}
}

void query(int nod,int l,int r,int a,int b){
	if(l>r || a>b) return;
	if(a<=l && b>=r){
		if(val<Arb[nod].Max){                 //daca subsirul care se termina in Arb[nod].pos este mai mare pastram datele noi  
			val=Arb[nod].Max;
			Pos=Arb[nod].pos;
		}
		return;
	}
	int mid=(l+r)/2;
	if(a<=mid) query(nod*2,l,mid,a,b);
	if(b>mid) query(nod*2+1,mid+1,r,a,b);
}

int main(){

	ifstream f("scmax.in");
	ofstream g("scmax.out");

	int x,n,N=0,Best=0,end;
	f >> n;
	for(i=1;i<=n;i++){
		f >> d[i];
		v[i]=mp(d[i],i);
	}
	sort(v+1,v+n+1);      
	for(i=1;i<=n;i++){
		if(v[i].ff!=v[i-1].ff) N++;
		pozA[v[i].ss]=N;            //pozitia din arbore a elementului de pe pozitia v[i].ss               
	}

	for(i=1;i<=n;i++){
		Pos=val=0;
		query(1,1,N,1,pozA[i]-1);
		last[i]=Pos;                 //pozitia ultimului element din cel mai mare subsir gasit  
		val++;
		Pos=pozA[i];
		if(val>Best){
			Best=val;           //lungimea celui mai lung subsir si pozitia in care se termina 
			end=i;
		}
		update(1,1,N,i);                       
	}

	for(;end;end=last[end]){
		S.push(d[end]);		
	}

	g << Best <<"\n";

	while(!S.empty()){
		g << S.top() <<" ";
		S.pop();
	}
		
}