Cod sursa(job #3213609)

Utilizator PalcPalcu Stefan Palc Data 13 martie 2024 12:13:31
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>
using namespace std;

/**
    1 2 3 4  5 6 7 8 9 10 11 12 13 14 15 16
a = 8 5 7 1 20 4 6 8 9  2 12 10 11  8  0 30

dp[i] = capatul minim drept al unui subsir de lungime i
P[i] = pozitia in care se depune valoarea a[i] in dp[]

     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
P  = 1 1 2 1 3 2 3 4 5  2  6  6  7  4  1  8
dp = 8
dp = 5
dp = 5 7
dp = 1 7
dp = 1 7 20
dp = 1 4 20
dp = 1 4 6
dp = 1 4 6 8
dp = 1 4 6 8 9
dp = 1 2 6 8 9
dp = 1 2 6 8 9 12
dp = 1 2 6 8 9 10
dp = 1 2 6 8 9 10 11
dp = 0 2 6 8 9 10 11
dp = 0 2 6 8 9 10 11 30
La fiecare pas i caut binar in dp cea mai din stanga pozitie p cu a[i]<=dp[p]

*/

int a[100003], P[100003], n, sol[100003];
int dp[100003], k;
ifstream fin("scmax.in");
ofstream fout("scmax.out");

void CautBin(int i)
{
    int st, dr, p, mij, x = a[i];
    if (x <= dp[1])
    {
        dp[1] = x;
        P[i] = 1;
        return;
    }

    if (x > dp[k])
    {
        k++;
        dp[k] = x;
        P[i] = k;
        return ;
    }

    /// caut cea mai din stanga poz. p cu a[i]<= dp[p]
    st = 1; dr = k; p = k;
    while (st <= dr)
    {
        mij = (st + dr) / 2;
        if (x <= dp[mij])
        {
            p = mij;
            dr = mij - 1;
        }
        else st = mij + 1;
    }
    dp[p] = x;
    P[i] = p;
}

int main()
{
    int i, j, len, ult;
    fin >> n;
    for (i = 1; i <= n; i++)
        fin >> a[i];
    dp[1] = a[1];
    P[1] = 1;
    k = 1; /// lungimea lui dp[]
    for (i = 2; i <= n; i++)
        CautBin(i);
    fout << k << "\n";
    ult = 2000000001;
    j = 0;
    for (len = k, i = n; i >= 1 && len > 0; i--)
        if (P[i] == len && a[i] < ult)
        {
            ult = a[i];
            sol[++j] = a[i];
            len--;
        }
    for (i = k; i >= 1; i--)
        fout << sol[i] << " ";
    fout.close();
    return 0;
}