Cod sursa(job #2124974)

Utilizator loo_k01Luca Silviu Catalin loo_k01 Data 7 februarie 2018 19:32:05
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <bits/stdc++.h>

using namespace std;
/**
    SURSA ASTA E CU INDICI CA SA VAD DACA INTRA, *WINK*... Nu ma judeca, pls!
    dp[i] = capatul minim al unui subsir de lungime i
    poz[i] = pozitia unde s-a inserat a[i] in vectorul dp
*/

const int Nmax = 1E5 + 5;
int a[Nmax];
int dp[Nmax];
int poz[Nmax];
int n, k;
int sol[Nmax];

void Read()
{
    ifstream fin("scmax.in");
    fin >> n;
    for (int i = 1; i <= n; i++)
        fin >> a[i];
    fin.close();
}

/// caut in dp[1..k] cea mai din stanga pozitie md cu x <= dp[md]
int Binary_Search(int x)
{
    int st, dr, md;
    int poz;
    st = 1; dr = k;
    poz = k;
    while (st <= dr)
    {
        md = (st + dr) / 2;
        if (x <= a[dp[md]])
        {
            poz = md;
            dr = md - 1;
        }
        else st = md + 1;
    }
    return poz;
}

void LIS()
{
    int i, x, p;
    /// Initializari
    dp[1] = 1;
    poz[1] = 1;
    k = 1;

    for (i = 2; i <= n; i++)
    {
        x = a[i];
        if (x > a[dp[k]]) /// Putem lungi subsirul LEJER
        {
            dp[++k] = i;
            poz[i] = k;
        }
        ///     OPTIONAL                            (ca)
        else if (x <= a[dp[1]]) /// Daca este mai mic decat toate il bagam JAPK la inceput
        {
            dp[1] = i;
            poz[i] = 1;
        }
        else /// Trebuie inserat undeva unde va actuliza un minim
        {                                   ///      (<--)
            /// Scrie mai sus -> Cea mai din stanga pozitie cu x <= dp[pozitie] pe (1..k)
            p = Binary_Search(x);
            dp[p] = i; /// Actualizam minimul ala
            poz[i] = p;
        }
    }
}

void Reconstructie()
{
    ofstream fout("scmax.out");
    fout << k << "\n";
    int i, lg;
    lg = k;
    ///     RECONSTITUIM
    for (i = n; lg > 0 && i >= 1; i--)
        if (poz[i] == lg)
            sol[lg--] = a[i];
    ///       AFISAM
    for (i = 1; i <= k; i++)
        fout << sol[i] << " ";
    fout << "\n";
    fout.close();
}

int main()
{
    Read();
    LIS();
    Reconstructie();
    return 0;
}