Cod sursa(job #823985)
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int bineary_search( int *v, int *M, int left, int right, int x ){
int aux = right;
int mid = ( left + right ) / 2;
while ( left <= right ){
if( ( v[M[mid]] < x ) && ( x <= v[M[mid+1]] ) ) return mid;
else if( x > v[M[mid+1]] ){
left = mid + 1;
mid = ( left + right ) / 2;
}
else{
right = mid - 1;
mid = ( left + right ) / 2 ;
}
}
return aux;
}
int N;
int main( int argc, char* argv[] ){
ifstream in("scmax.in");
ofstream out("scmax.out");
in >> N;
int nr = 1; // initial length
int max = 0;
int p = 0;
int* v = new int[N+1];
int* M = new int[N+1];
int* best = new int[N+1];
int* prev = new int[N+1];
int* stack = new int[N+1];
v[0] = 0;
for( int i = 1; i <= N; i++ )
in >> v[i];
in.close();
M[0] = 0; // dummy value == 0
M[1] = 1; // for v[1]
memset( best, 1, (N+1)*sizeof(int) );
memset( prev, -1, (N+1)*sizeof(int) );
for( int i = 2; i <= N; i++ ){
int idx = bineary_search( v, M, 0, nr, v[i] );
M[idx+1] = i;
prev[i] = M[idx]; // introduc in prev[i] cel mai mare element mai mic decat noul el introdus v[i]
best[i] = idx + 1;
if( best[i] > max ){
max = best[i];
p = i;
}
if( nr < idx + 1 )
nr++;
}
out << max << endl;
int k = 0;
while ( p > 0 ){
stack[k++] = v[p];
p = prev[p];
}
for( int i = k-1 ; i >= 0 ; i-- )
out << stack[i]<<" ";
out.close();
delete []v;
delete []M;
delete []best;
delete []prev;
delete []stack;
return 0;
}