Cod sursa(job #3290260)

Utilizator Lex._.Lexi Guiman Lex._. Data 29 martie 2025 18:02:25
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.1 kb
#include <bits/stdc++.h>
using namespace std;

int a[100001]; //vectorul citit
vector<int> LIS; //salvam in LIS pozitiile elementelor sirului crescator
int modificare[100001]; //pentru fiecare numar din a, salvam pozitia din LIS unde s-a produs modificarea atunci cand am pus numarul in LIS

int cautare_binara(int val, int dr)
{
    int poz=0, st=0;
    while(st<=dr)
    {
        int mij=st+(dr-st)/2;
        if(val<=a[LIS[mij]])
        {
            poz=mij;
            dr=mij-1;
        }
        else
            st=mij+1;
    }
    return poz;
}

int main()
{
    ifstream cin("scmax.in");
    ofstream cout("scmax.out");
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> a[i]; //citim vectorul
    LIS.reserve(n);
    for(int i=0; i<n; i++)
    {
        if(LIS.empty())
        {
            LIS.push_back(i);
            modificare[i]=LIS.size()-1;
        }
        else
        {
            if(a[i]>a[LIS.back()])
            {
                LIS.push_back(i);
                modificare[i]=LIS.size()-1;
            }
            else
            {
                int pozitie=cautare_binara(a[i], LIS.size()-1);
                LIS[pozitie]=i;
                modificare[i]=pozitie;
            }
        }
    }
    cout << LIS.size() << "\n"; //afisam lungimea subsirului

    //afisam elementele subsirului crescator
    vector<int> afisare; //numerele ce trebuie afisate
    afisare.reserve(LIS.size());
    int nr=LIS.size()-1; //numarul cautat la fiecare pas
    for(int i=n-1; i>=0; i--) //vom parcurge tot sirul in ordine inversa si vom cauta prima aparitie in vectorul modificare a fiecarui numar de la LIS.size() la 1, apoi salvam numarul in afisare
    {
        if(modificare[i]==nr) //prima aparitie in vectorul modificare a numarului cautat
        {
            afisare.push_back(a[i]); //salvam numarul in afisare
            nr--; //trecem la numarul mai mic
        }
    }
    for(int i=afisare.size()-1; i>=0; i--) //afisam numerele din cel mai lung subsir crescator
        cout << afisare[i] << " ";

    return 0;
}