Cod sursa(job #1256999)

Utilizator angelaAngela Visuian angela Data 7 noiembrie 2014 07:08:38
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.7 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

const int Dim = 100001;


int a[Dim], aib[Dim], n;
int L[Dim], Lmax, t[Dim], v[Dim];
vector<int> A;

void Update(int v, int i); 
int Query(int v);   // pozitia maximului L[1]...L[i - 1] (v + 1 e valoarea la poz i) 
void Write(int i);
void Deb();

int main() 
{
    fin >> n;
    
    for(int i = 1; i <= n; ++ i) 
    {
        fin >> a[i];
        v[i] = a[i];
        A.push_back(v[i]);
    }
   
    // normalizare
    sort(A.begin(), A.end());
    A.erase(unique(A.begin(), A.end()), A.end());
    
    for(int i = 1; i <= n; ++ i)
        v[i] = 1 + lower_bound(A.begin(), A.end(), v[i]) - A.begin();
    // v[i] = al catelea ca marime este a[i] in sirul a
	
//	Deb();
	
    int imax = 1;
    int j;
    for (int i = 1 ; i <= n ; ++ i) 
    {
        j = Query(v[i] - 1);
        t[i] = j;
        L[i] = L[j] + 1;
        
        Update(v[i], i);
    
        if(L[imax] < L[i])
            imax = i;
    }
    
    fout << L[imax] << '\n';
    Write(imax);
    
    fout.close();
    return 0;
}

void Update(int v, int i) 
{ 
    for (; v <= n; v += v & -v)
       if ( L[i] > L[aib[v]] )
			aib[v] = i;
}

int Query(int v) 
{
    int j = 0;
    for ( ; v > 0 ; v -= v & -v)
        if ( L[aib[v]] > L[j])
			j = aib[v]; 
            
    return j; 
}

void Write(int i)
{
	if ( !i ) return;
	Write(t[i]);
	fout << a[i] << ' ';
}

void Deb()
{
	for(int i = 1; i <= n; ++i)
		fout << a[i] << ' ';
	fout << '\n';
	for(int i = 1; i <= n; ++i)
		fout << v[i] << ' ';
	fout << '\n';
}