Cod sursa(job #735369)

Utilizator vladtarniceruVlad Tarniceru vladtarniceru Data 16 aprilie 2012 11:38:02
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include <fstream>
#include <cstdio>
#include <algorithm>
using namespace std;

int n,v[100100],ab[100100],sol,poz[100100],ab2[100100],sl[100100],vi[100100];
int a[100100];
pair<int,int> abc;

inline void update(int poz,int val,int aaa)
{
    for(int i=poz;i<=n;i+=i&(-i))
    {
        if(ab[i]<val)
        {
            ab[i]=val;
            ab2[i]=aaa;
        }
    }
}

inline void query(int poz)
{
    //int sol=0,sol2=0;
    abc.first=abc.second=0;
    for(int i=poz-1;i>=1;i-=i&(-i))
    {
        if(abc.first<ab[i]) abc.first=ab[i],abc.second=ab2[i];
    }
}

inline int bs(int val)
{
    int cnt=1<<20,i=1;
    for(;cnt>0;cnt>>=1)
    {
        if(i+cnt<=n)
        {
            if(a[i+cnt]<=val)
            {
                i+=cnt;
            }
        }
    }
    return i;
}

int main()
{
    ifstream in("scmax.in");
    freopen("scmax.out","w",stdout);

    in>>n;
    for(int i=1;i<=n;++i)
    {
        in>>a[i];
        vi[i]=a[i];
        v[i]=a[i];
    }

    sort(a+1,a+n+1);

    for(int i=1;i<=n;++i)
    {
        a[++a[0]]=a[i];
        while(a[i]==a[i+1]) ++i;
    }

    for(int i=1;i<=n;++i)
    {
        v[i]=bs(v[i]);
    }

    update(v[1],1,1);
    for(int i=2;i<=n;++i)
    {
        query(v[i]);
        poz[i]=abc.second;
        sl[i]=abc.first+1;
        update(v[i],1,i);
        update(v[i],abc.first+1,i);
    }

    int pz=0;
    for(int i=1;i<=n;++i)
    {
        if(sol<sl[i])
        {
            sol=sl[i];
            pz=i;
        }
    }

    printf("%d\n",sol);
    while(pz>0)
    {
        sl[++sl[0]]=vi[pz];
        pz=poz[pz];
    }

    for(int i=sl[0];i>=1;--i)
    {
        printf("%d ",sl[i]);
    }

    printf("\n");
    return 0;
}