Cod sursa(job #735359)

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

int n,v[100100],ab[100100],sol,poz[100100],ab2[100100],sl[100100],c2[100100],vi[100100];
int a[100100];

struct cmp
{
    inline bool operator()(const pair<int,int> &a,const pair<int,int> &b)const
    {
        return a.first<b.first;
    }
};

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 pair<int,int> query(int poz)
{
    int sol=0,sol2=0;
    for(int i=poz-1;i>=1;i-=i&(-i))
    {
        if(sol<ab[i]) sol=ab[i],sol2=ab2[i];
    }
    return make_pair(sol,sol2);
}

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");
    ofstream out("scmax.out");

    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)
    {
        v[i]=bs(v[i]);
    }

    update(v[1],1,1);
    for(int i=2;i<=n;++i)
    {
        pair<int,int> abc=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;
        }
    }

    out<<sol<<'\n';
    while(pz>0)
    {
        sl[++sl[0]]=vi[pz];
        pz=poz[pz];
    }

    for(int i=sl[0];i>=1;--i)
    {
        out<<sl[i]<<' ';
    }

    out<<'\n';
    out.close();
    return 0;
}