Cod sursa(job #329519)

Utilizator DraStiKDragos Oprica DraStiK Data 6 iulie 2009 14:12:46
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <algorithm>
#define DIM 100005
using namespace std;

struct numar {int x,n;} a[DIM];
int prec[DIM],best[DIM],aib[DIM];
int n,maxim,indice;

int cbin (int val)
{
    int st,dr,mij,sol;
    for (st=1, dr=n; st<=dr; )
    {
        mij=(st+dr)/2;
        if (prec[mij]==val)
            sol=mij;
        if (prec[mij]<val)
            st=mij+1;
        else
            dr=mij-1;
    }
    return sol;
}

void read ()
{
    int i,j;
    scanf ("%d",&n);
    for (i=1; i<=n; ++i)
    {
        scanf ("%d",&a[i].x);
        prec[i]=a[i].x;
    }
    sort (prec+1,prec+n+1);
    for (i=j=1; i<=n; ++i)
        if (prec[i]!=prec[j])
            prec[++j]=prec[i];
    for (i=1; i<=n; ++i)
        a[i].n=cbin (a[i].x);
}

int lsb (int x)
{
    return x&(x-1)^x;
}

int query (int poz)
{
    int i=0;
    for ( ; poz; poz-=lsb (poz))
        if (best[aib[poz]]>best[i])
            i=aib[poz];
    return i;
}

void update (int poz,int val)
{
    for ( ; poz<=n; poz+=lsb (poz))
        if (best[val]>best[aib[poz]])
            aib[poz]=val;
}

void print (int poz)
{
    if (prec[poz])
        print (prec[poz]);
    printf ("%d ",a[poz].x);
}

void solve ()
{
    int i;
    for (i=1; i<=n; ++i)
    {
        prec[i]=query (a[i].n-1);
        best[i]=best[prec[i]]+1;
        update (a[i].n,i);
        if (best[i]>maxim)
        {
            maxim=best[i];
            indice=i;
        }
    }
    printf ("%d\n",maxim);
    print (indice);
}

int main ()
{
    freopen ("scmax.in","r",stdin);
    freopen ("scmax.out","w",stdout);
    read ();
    solve ();
    return 0;
}