Cod sursa(job #253567)

Utilizator c_sebiSebastian Crisan c_sebi Data 5 februarie 2009 22:47:40
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <fstream>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;

#define DIM 263000
#define Max(a, b) ((a)>=(b)?(a):(b))

int A[DIM], n, v[100001], x[100001], ind[100001], maxim, sol[100001];
ofstream g("scmax.out");

void update(int nod, int st, int dr, int poz, int val){
	if(st == dr){
		A[nod] = val;
	}	else {
		int m = (st + dr) >> 1;
		if(poz <= m) update(2*nod, st, m, poz, val);
		else update(2*nod + 1, m + 1, dr, poz, val);
		A[nod] = Max(A[2*nod], A[2*nod + 1]);
	}
}

void query(int nod, int st, int dr, int a, int b){
	if(a<=st && dr<=b){
		if(A[nod] > maxim) maxim = A[nod];
	} else{
		int m = (st + dr) >> 1;
		if(a <= m) query(2*nod, st, m, a, b);
		if(b > m) query(2*nod + 1, m+1, dr, a, b);
	}
}

int main(){
        ifstream f("scmax.in");
        f>>n;
	int i;
	for(i = 1; i <= n; i++)
                {f>>v[i]; x[i] = v[i]; }
        sort(x + 1, x + n + 1);
        for(i = 1; i <= n; i++)
                ind[i] = lower_bound(x + 1, x + n + 1, v[i]) - x;
        memset(x, 0, sizeof(x));
        x[1] = 1;
	int m = 0, pm;
	for(i = 1; i <= n; i++){
		maxim = -1;
		if(ind[i]==1) maxim = 0; else query(1, 1, n, 1, ind[i]-1);
		x[i] = 1 + maxim;
		if(m < x[i]) { m = x[i]; pm = i; }
		update(1, 1, n, ind[i], x[i]);
	}
        g<<m<<endl;
        sol[1] = v[pm]; int ns = 1;
        for(i = pm-1; i > 0; i--){
          if(x[i]+1 == x[pm]){
                sol[++ns] = v[i];
                pm = i;
             }
           }
        for(;ns; ns--) g<<sol[ns]<<" ";

	return 0;
}