Cod sursa(job #2683651)

Utilizator Albert_GAlbert G Albert_G Data 11 decembrie 2020 21:16:09
Problema Subsir crescator maximal Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <fstream>
#include <algorithm>
using namespace std;

ifstream in("scmax.in");
ofstream out("scmax.out");

constexpr int N = 1e5+1;
int v[N],vmin[N],l[N];
///vmin[x]=val min cu care se termina un subsir de lung x
///l[i] = lungimea maxima a unui subsir care se are ultimul element v[i]

int cbin(int* vmin,int st, int dr, int val)
{
    ///caut cel mai mare index pt care vmin[index]<=val
    if(val>vmin[dr]) return dr+1;
    int mij;
    while(st<dr)
    {
        mij = (st+dr)/2;
        if(v[mij]>=val) dr=mij;
        else st = mij+1;
    }
    return st;
}
///lungimea maxima a unui subsir e cate elem are vmin[]
void afisare_subsir(int* vmin,int* l, int imax)
{
    if(imax<=0)
        return;
    int pos = imax-1;
    while(pos>0 && l[pos]!=l[imax]-1)
        --pos;
    afisare_subsir(vmin,l,pos);
    out<<v[imax]<<' ';
}

int main()
{
    int n;
    in>>n;
    for(auto i=v+1;i<=v+n;++i)
        in>>*i;
    int lmax=0,pos;
    for(int i = 1;i<=n;++i)
    {
        pos = cbin(vmin,1,lmax,v[i]);
        lmax = max(lmax,pos);
        vmin[pos] = v[i];
        l[i] = pos;
    }
    out<<lmax<<'\n';
    int imaxlen = n;
    ///gasim indexul la care se termina secventa de lungime maxima
    while(l[imaxlen]!=lmax)
        --imaxlen;
    afisare_subsir(vmin,l,imaxlen);
    return 0;
}