Cod sursa(job #705479)

Utilizator balakraz94abcd efgh balakraz94 Data 4 martie 2012 14:23:36
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.7 kb
#include <cstdio>
#include <algorithm>
#define infile "scmax.in"
#define outfile "scmax.out"
#define n_max 100005
#define zeros(x) ((x^(x-1))&x)
using namespace std;

int lst[n_max], v[n_max], a[n_max], prev[n_max], Lg[n_max];

int AIB[n_max];

int N;


void citeste()
{
    freopen(infile, "r", stdin);
    
    scanf("%d", &N);
    
    for (int i = 1; i <= N; ++i)
    {
        scanf("%d", &a[i]);
        
        v[i] = lst[i] = a[i];
    }
    
    fclose(stdin);
}


void update(int x, int poz)
{
	for(; x<=N; x += zeros(x))
		if(Lg[AIB[x]] < Lg[poz])
			AIB[x] = poz;
}


int query(int x)
{
	int pmax = 0;
	for(; x; x -= zeros(x))
		if(Lg[AIB[x]] > Lg[pmax])
			pmax = AIB[x];
		
	return pmax;
}



void rezolva()
{ 
	sort(lst+1, lst+N+1);//sortez valorile
	
	for(int i=1; i<=N; ++i)//normalizez valorile in vectorul v
		v[i] = lower_bound(lst+1, lst+N+1, v[i]) - lst;
	
	for(int i=1; i<=N; ++i)
	{
		prev[i] = query(v[i]-1);//caut pozitia elementului < v[i] care are Lg maxim
		Lg[i] = Lg[prev[i]] + 1;//actualizez lungimea
		update(v[i], i);//actualizez intervalul...daca Lg[i] este c.m.mare pe intervalul [1, v[i]]
	}
	
	int Best = 0;
	for(int i=1;i<=N; ++i)
		if(Lg[i] > Lg[Best])//caut pozitia elementului cu Lg maxim
			Best = i;
		
	lst[0] = 0;
	for(; Best; Best = prev[Best])//merg din fiu in tata
		lst[++lst[0]] = a[Best];//salvez in solutie valoarea initiala
}


void afiseaza()
{
    freopen(outfile, "w", stdout);

	printf("%d\n", lst[0]);
	
	for(int i = lst[0]; i; --i)
		printf("%d ", lst[i]);
	
	printf("\n");	
	
    fclose(stdout);
}


int main(void)
{
    citeste();
    rezolva();
    afiseaza();
    
    return 0;
}