Cod sursa(job #1246094)

Utilizator sefubanilorSefu Banilor sefubanilor Data 20 octombrie 2014 16:25:35
Problema Subsir crescator maximal Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <fstream>
#include <algorithm>
#include <iostream>

using namespace std;

const char InFile[]="scmax.in";
const char OutFile[]="scmax.out";
const int MaxN=100111;

ifstream fin(InFile);
ofstream fout(OutFile);

int N,prev[MaxN],V[MaxN],P[MaxN],Pp[MaxN],best[MaxN],AIB[MaxN],bestInd,bestSol;

struct CMP
{
    inline bool operator() (const int &A, const int &B)
    {
        if(V[A]==V[B])
        {
            return A<B;
        }
        return V[A]>V[B];
    }
};

void afis(int ind)
{
    if(!ind)
    {
        return;
    }
    afis(prev[ind]);
    fout<<V[ind]<<" ";
}

inline int LSB(const int &x)
{
    return x&-x;
}

inline int QueryAIB(int pos)
{
    int sol=0;
    for(;pos<MaxN;pos+=LSB(pos))
    {
        if(best[AIB[pos]]>best[sol])
        {
            sol=AIB[pos];
        }
    }
    return sol;
}

inline void UpdateAIB(int pos, int val)
{
    for(;pos;pos-=LSB(pos))
    {
        if(best[AIB[pos]]<best[val])
        {
            AIB[pos]=val;
        }
    }
}

int main()
{
    fin>>N;
    for(int i=1;i<=N;++i)
    {
        fin>>V[i];
        P[i]=i;
    }
    fin.close();

    sort(P+1,P+1+N,CMP());

    for(int i=1;i<=N;++i)
    {
        Pp[P[i]]=i;
    }

    for(int i=1;i<=N;++i)
    {
        prev[i]=QueryAIB(Pp[i]);
        best[i]=best[prev[i]]+1;
        UpdateAIB(Pp[i],i);

        if(best[i]>bestSol)
        {
            bestSol=best[i];
            bestInd=i;
        }
    }

    fout<<bestSol<<"\n";
    afis(bestInd);

    fout.close();
    return 0;
}