Cod sursa(job #3309780)

Utilizator Lex._.Lex Guiman Lex._. Data 8 septembrie 2025 22:02:28
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;

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

int a[NMAX];
int sortat[NMAX], ult_poz[NMAX], lungime[NMAX];
pair<int, int> aib[NMAX]; /// aib[i].first = maximul  iar  aib[i].second = pozitia elementului maxim

int cautare_binara(int val, int n) ///cautam cate numere din sir sunt mai mici ca val
{
    int st=0, dr=n, poz=0;
    while(st<=dr)
    {
        int mij=st+(dr-st)/2;
        if(sortat[mij]<=val)
        {
            poz=mij;
            st=mij+1;
        }
        else
        {
            dr=mij-1;
        }
    }
    return poz;
}

void actualizare(int val, int i, int poz, int n) ///actualizare aib
{
    while(poz<=n)
    {
        if(val>aib[poz].first)
        {
            aib[poz].first=val;
            aib[poz].second=i;
        }
        poz+=(poz&(-poz));
    }
}

pair<int, int> maxim(int poz, int n) ///maximul pe intervalul [1, poz] si pozitia sa
{
    pair<int, int> maxim={0, 0};
    while(poz>0)
    {
        if(aib[poz].first>maxim.first)
        {
            maxim=aib[poz];
        }
        poz-=(poz&(-poz));
    }
    return maxim;
}

int main()
{
    int n;
    in >> n;
    for(int i=1; i<=n; i++)
    {
        in >> a[i];
        sortat[i]=a[i];
    }
    sort(sortat+1, sortat+n+1);
    int l_max=0, poz_lmax=0; ///lungimea maxima si pozitia din vectorul a a ultimului element adaugat
    for(int i=1; i<=n; i++)
    {
        int poz=cautare_binara(a[i], n);
        pair<int, int> l_maxim=maxim(poz-1, n); ///lungimea maxima si pozitia ultimului element al subsirului crescator de lungime maxima de pana acum (care are ultimul element mai mic ca a[i])
        lungime[i] = l_maxim.first + 1;
        ult_poz[i] = l_maxim.second;

        if(lungime[i]>l_max)
        {
            l_max=lungime[i];
            poz_lmax=i;
        }
        actualizare(lungime[i], i, poz, n);
    }
    out << l_max << "\n";

    vector<int> lis; ///subsirul cerut
    while(poz_lmax!=0)
    {
        lis.push_back(poz_lmax);
        poz_lmax=ult_poz[poz_lmax];
    }
    reverse(lis.begin(), lis.end());

    for(auto& i : lis) ///afisam subsirul
        out << a[i] << " "; out << "\n";

    return 0;
}