Cod sursa(job #1650427)

Utilizator LolkekzorChiorean Tudor Lolkekzor Data 11 martie 2016 18:15:56
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
#include <fstream>
#include <algorithm>
#define f first
#define s second
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");

pair<int, int> sortedVals[100010];
int arbore[4 * 100000 + 10], tati[100010], initialVals[100010];
int n, i, limita, lung, poz, val, bestLung, bestStart;

void getMaxLength(int nod, int st, int dr) {
    if (st >= limita) return;

    int mij = (st + dr) / 2;

    if (dr <= limita) {
        if (arbore[nod] > lung) {
            while (st != dr) {
                mij = (st + dr) / 2;
                if (arbore[nod] == arbore[nod * 2]) {
                    dr = mij;
                    nod = nod * 2;
                } else {
                    st = mij + 1;
                    nod = nod * 2 + 1;
                }
            }

            lung = arbore[nod];
            poz = st;
        }
        return;
    }

    getMaxLength(nod * 2, st, mij);
    getMaxLength(nod * 2 + 1, mij + 1, dr);
}

void updateArbore(int nod, int st, int dr) {
    if (st == dr) {
        arbore[nod] = val;
        return;
    }

    int mij = (st + dr) / 2;

    if (poz <= mij)
        updateArbore(nod * 2, st, mij);
    else
        updateArbore(nod * 2 + 1, mij + 1, dr);

    arbore[nod] = max(arbore[nod * 2], arbore[nod * 2 + 1]);
}

bool cmp(pair<int,int> a, pair<int,int> b) {
    if (a.f == b.f)
        return a.s > b.s;
    else
        return a.f < b.f;
}

void reConstruct(int pos) {
    if (pos != 0)
        reConstruct(tati[pos]);
    if (pos != 0)
        fout<<initialVals[pos]<<' ';
}

int main() {
    fin>>n;
    for (i = 1 ; i <= n ; i++) {
        fin>>sortedVals[i].f;
        sortedVals[i].s = i;

        initialVals[i] = sortedVals[i].f;
    }
    sort(sortedVals + 1, sortedVals + n + 1, cmp);

    for (i = 1 ; i <= n ; i++) {
        lung = 0;
        poz = 0;
        limita = sortedVals[i].s;
        getMaxLength(1, 1, n);
        tati[sortedVals[i].s] = poz;

        if (lung >= bestLung) {
            bestLung = lung;
            bestStart = sortedVals[i].s;
        }

        val = lung + 1;
        poz = sortedVals[i].s;
        updateArbore(1, 1, n);
    }

    fout<<bestLung + 1<<'\n';
    reConstruct(bestStart);
}