Cod sursa(job #253576)

Utilizator c_sebiSebastian Crisan c_sebi Data 5 februarie 2009 23:22:27
Problema Subsir crescator maximal Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <string.h>
#include <map>
#include <stdio.h>
#include <algorithm>
using namespace std;

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

int A[DIM], n, v[100001], x[100001], maxim, sol[100001];
map<int, int> table;

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(nod<<1, st, m, poz, val);
		else update((nod<<1) + 1, m + 1, dr, poz, val);
		A[nod] = Max(A[nod<<1], A[(nod<<1) + 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(nod<<1, st, m, a, b);
		if(b > m) query((nod<<1) + 1, m+1, dr, a, b);
	}
}

int main(){
        FILE *f = fopen("scmax.in", "r");
        FILE *g = fopen("scmax.out", "w");
        fscanf(f, "%d", &n);
	int i;
	for(i = 1; i <= n; i++)
                {fscanf(f, "%d", &v[i]); x[i] = v[i]; }
        sort(x + 1, x + n + 1);
        table.clear();
        int tot = 1, j;
        for(i = 1; i <= n; ){
                table[x[i]] = tot++;
                j = i;
                while(j <= n && x[i] == x[j]) j++;
                i = j;
        }
        
        memset(x, 0, sizeof(x));
        x[1] = 1;
	int m = 0, pm;
	for(i = 1; i <= n; i++){
		maxim = -1;
                j = table[v[i]];
		if(j==1) maxim = 0; else query(1, 1, n, 1, j-1);
		x[i] = 1 + maxim;
		if(m < x[i]) { m = x[i]; pm = i; }
		update(1, 1, n, j, x[i]);
	}
        fprintf(g, "%d\n", m);
        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--) fprintf(g, "%d ", sol[ns]);

	return 0;
}