Cod sursa(job #3196467)

Utilizator raileanu-alin-gabrielRaileanu Alin-Gabriel raileanu-alin-gabriel Data 23 ianuarie 2024 22:39:56
Problema Subsir crescator maximal Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <fstream>
#include <map>
#include <set>
#define s second
#define f first
const int NMAX=100005;

using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");

pair<int, int> aint[4*NMAX];
pair<int, int> dp[NMAX];
int a[NMAX], n;
map <int, int> poz;
set <int> s;

void find(int);
void update(int, int, int, int, pair<int, int>);
pair<int, int> query(int, int, int, int, int);

int main()
{
    int i, cnt=0;
    pair<int, int> p;
    fin>>n;
    for(i=1; i<=4*n; i++) aint[i]={0, 0};
    for(i=1; i<=n; i++)
    {
        fin>>a[i];
        s.insert(a[i]);
    }
    for(auto i:s) poz[i]=++cnt;
    for(i=1; i<=n; i++)
    {
        dp[i]=max({0, i}, query(1, 1, s.size(), 1, poz[a[i]]-1));
        dp[i].f++;
        update(1, 1, s.size(), poz[a[i]], {dp[i].f, i});
    }
    p=query(1, 1, n, 1, s.size());
    fout<<p.f<<'\n';
    find(p.s);
    return 0;
}

void find(int poz)
{
    if(poz==0) return;
    if(poz!=dp[poz].s) find(dp[poz].s);
    fout<<a[poz]<<' ';
}

pair<int, int> query(int nod, int st, int dr, int qst, int qdr)
{
    if(qst>qdr) return {0, 0};
    if(st>=qst && dr<=qdr) return aint[nod];
    int mij=(st+dr)/2;
    pair<int, int> v1={0, 0}, v2={0, 0};
    if(qst<=mij) v1=query(2*nod, st, mij, qst, qdr);
    if(mij<qdr) v2=query(2*nod+1, mij+1, dr, qst, qdr);
    return max(v1, v2);
}

void update(int nod, int st, int dr, int poz, pair<int, int> val)
{
    if(st==dr)
    {
        aint[nod]=max(aint[nod], val);
        return;
    }
    int mij=(st+dr)/2;
    if(poz<=mij) update(2*nod, st, mij, poz, val);
    else update(2*nod+1, mij+1, dr, poz, val);
    aint[nod]=max(aint[2*nod], aint[2*nod+1]);
}