Cod sursa(job #410700)

Utilizator floringh06Florin Ghesu floringh06 Data 4 martie 2010 15:47:13
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <cstdio>
#include <cstring>

using namespace std;

#define FIN "scmax.in"
#define FOUT "scmax.out"
#define MAX_N 100005

int v[MAX_N];
int d[MAX_N], blist[MAX_N], pred[MAX_N], len;

int N;

int bsearch (int e)
{
    if (e > v[ blist[len] ]) return len;
    
    int li = 0, lf = len, m;
    while (li <= lf)
    {
          m = (li + lf) >> 1;
          if (v[ blist[m] ] < e && e <= v[ blist[m + 1] ]) return m;
          if (v[ blist[m + 1] ] < e) li = m + 1;
                                else lf = m - 1;
    }
    return 0;
}

void getsolution (int c)
{
     if (pred[c] > 0) 
        getsolution(pred[c]);
     printf ("%d ", v[c]);
}

void solve ()
{
     int i;
     
     for (i = 1; i <= N; ++i)
     {
         int lstp = bsearch(v[i]);
         
         pred[i] = blist[lstp];
         d[i] = d[blist[lstp]] + 1;
         
         if (len == lstp)
             blist[++len] = i;
         else
             if (v[ blist[lstp + 1] ] > v[i])
                blist[lstp + 1] = i;
     }
     
     int BEST = -1;
     int posBEST;
     for (i = 1; i <= N; ++i)
         if (d[i] > BEST) {
                  BEST = d[i];
                  posBEST = i;
         }
     printf ("%d\n", BEST);
     getsolution(posBEST);
}

int main ()
{
    freopen (FIN, "r", stdin);
    freopen (FOUT, "w", stdout);
    
    scanf ("%d", &N);
    for (int i = 1; i <= N; ++i)
        scanf ("%d", v + i);
        
    solve ();
    
    return 0;
}