Cod sursa(job #676740)

Utilizator Bit_MasterAlexandru-Iancu Caragicu Bit_Master Data 9 februarie 2012 16:05:45
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.18 kb
/*
    alte explicatii la sursa precedenta
    p[i] -> pozitia pe care se termina un subsir de lungime i
    Iau elementele din vectorul v in ordine (pentru a adauga
elemente noi numai la numere cu pozitii mai mici.
    Fiecare element il voi adauga la subsecventa de lungime maxima dintre cele posibile
(daca pe viitor voi gasi un element mai mic decat acesta care sa-i ia locul, il va lua,
adaugandu-se la secventa de lungime mai mica precedenta).
    Valorile vor fi crescatoare deoarece valorile de pe lungimi mai mari trebuie sa fie
mai mari decat cele pe lungimi mai mici (altfel nu se pot lega), deci pot folosi cautare
binara pentru a gasi subsecventa la care adaug.

    Cand adaug un element in p, ii retin si predecesorul (acesta nu se va modifica).
    Desi pe o anumita lungime pot plasa si elemente mai mici, ele nu vor putea fi folosite
decat de urmatoarele elemente (cu pozitie mai mare), cele de pe lungimi mai mari raman
"legate" de vechiul numar.
*/

#include <cstdio>
using namespace std;

const int N_MAX = 100010;
const int INF = 2000000010;

int v[N_MAX]; int n;
int p[N_MAX]; int l_max = 0;
int pred[N_MAX];

inline int max(int a, int b)
{
    return (a>b)?a:b;
}

void citeste()
{
    scanf("%d",&n);
    for (int i = 1; i <= n; ++i)
        scanf("%d",&v[i]);
}

int cautare_binara(int i)
{
    int poz = 0;
    for (int pas = 1<<20; pas > 0; pas >>= 1)
        if (poz + pas <= l_max && v[p[poz+pas]] < v[i])
            poz += pas;
    return poz;
}

void scmax()
{
    int l;
    v[0] = INF; //cand ma aflu pe o lungime ce nu exista, p[l] = 0 si INF este suficient de mare
    for (int i = 1; i <= n; ++i)
    {
        l = cautare_binara(i);
        if (v[p[l+1]] > v[i])
        {
            p[l+1] = i;
            l_max = max(l_max,l+1);
            pred[i] = p[l];
        }
    }
}

void scrie_subsir(int poz)
{
    if (pred[poz] != 0)
        scrie_subsir(pred[poz]);
    printf("%d ",v[poz]);
}

void scrie()
{
    printf("%d\n",l_max);
    scrie_subsir(p[l_max]);
}

int main()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);
    citeste();
    scmax();
    scrie();
    return 0;
}