Cod sursa(job #812602)
#include <stdio.h>
int a[100003],l[100003],p[100003],c[100003],index[100003],n,lmax,lpoz,i,j;
/*c[i] - valoarea minima a ultimului element al celui mai lung subsir de lungime i
l[i] - lungimea maxima a celui mai lung subsir care se termina cu a[i]
*/
//caut binar pozitia k pentru care c[k-1]<a[i]<=c[k]
int b_search(int dim, int x){
int i = 0, j = dim, m;
while ( i <= j ){
m = (i+j)/2;
if ( (c[m-1] < x) && (x <= c[m]) )
return m;
else if ( x < c[m] )
j = m-1;
else
i = m+1;
}
}
void max_length(){
int i,j,size,k;
c[1] = a[0]; l[0] = 1; p[0] = -1; index[1] = 0;
size = 1;
for (i=1;i<n;i++){
if (a[i] < c[1]){ //se schimba valoarea minima
c[1] = a[i];
index[1] = i;
l[i] = 1;
p[i] = -1;
}
else if (a[i] > c[size]){ //a[i] extinde cel mai lung subsir crescator
c[size+1] = a[i];
index[size+1] = i;
l[i] = size + 1;
p[i] = index[size];
size++;
}
else{ //caut binar pozitia k astfel incat c[k-1]<a[i]<=c[k]
k = b_search(size,a[i]);
c[k] = a[i];
index[k] = i;
l[i] = k;
p[i] = index[k-1];
}
if (l[i]>lmax){
lmax = l[i];
lpoz = i;
}
}
}
void print(FILE *out, int poz){
if (p[poz]!=-1)
print(out,p[poz]);
fprintf(out,"%d ",a[poz]);
}
int main(int arc, char *argv[]){
FILE *in, *out;
in = fopen("scmax.in","r");
out = fopen("scmax.out","w");
fscanf(in,"%d",&n);
for (i=0;i<n;i++)
fscanf(in,"%d",&a[i]);
max_length();
//afisare drum
fprintf(out,"%d\n",lmax);
print(out,lpoz);
fclose(in);
fclose(out);
}