Cod sursa(job #2683667)

Utilizator Albert_GAlbert G Albert_G Data 11 decembrie 2020 21:53:12
Problema Subsir crescator maximal Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.42 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=0;i<n;++i)
        in>>v[i];
    int lmax=1,pos;
    l[0]=1;
    vmin[0]=v[0];
    for(int i = 1;i<n;++i)
    {
        ///pos = cbin(vmin,1,lmax,v[i]);
        pos = lower_bound(vmin,vmin+lmax,v[i])-vmin;
        if(lmax==pos) ++lmax;
        vmin[pos] = v[i];
        l[i] = pos+1;
    }
    out<<lmax<<'\n';
    int imaxlen = n-1;
    ///gasim indexul la care se termina secventa de lungime maxima
    while(l[imaxlen]!=lmax)
        --imaxlen;
    afisare_subsir(vmin,l,imaxlen);
    return 0;
}