Cod sursa(job #2088623)

Utilizator ioanailincaMoldovan Ioana Ilinca ioanailinca Data 15 decembrie 2017 16:48:16
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
// sclm nlogn

#include <fstream>

using namespace std;

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

const int NMAX = 100001;

int a[NMAX];
int n;

int d[NMAX], t[NMAX];
int best[NMAX + 1]; // best[i] = indice cu valoarea minima cu care
                // se termina un subsir de lungime i

int lenBest; // lungimea maxima a unui subsir din toate posibile de pana acum
int maximGlobal = 0, pozmaxGlobal = 0;

inline void read() {
    fin >> n;
    for (int i = 1; i <= n; ++i)
        fin >> a[i];
}

inline void getSCLM() {
    int st, dr, mid;
    int ans;
    for (int i = 1; i <= n; ++i) {
        st = 1, dr = lenBest;
        ans = 0;
        while (st <= dr) {
            mid = (st + dr) / 2;

            if (a[best[mid]] > a[i]) {
                dr = mid - 1;
            }
            else {
                if (a[best[mid]] < a[i])
                    ans = mid;
                st = mid + 1;
            }
        }

        d[i] = d[best[ans]] + 1;
        t[i] = best[ans];

        if (d[i] >= maximGlobal) {
            maximGlobal = d[i];
            pozmaxGlobal = i;
        }

        if (ans == lenBest) {
            best[++lenBest] = i;
        }
        else if (a[best[ans]] < a[i] && a[i] < a[best[ans + 1]])
            best[ans + 1] = i;
    }
}

void getArray(int pos) {
    if (t[pos] == 0) {
        fout << a[pos] << ' ';
        return;
    }

    getArray(t[pos]);
    fout << a[pos] << ' ';
}

inline void write() {
    fout << maximGlobal << '\n';

    getArray(pozmaxGlobal);
}

int main()
{
    read();
    getSCLM();
    write();

    fin.close();
    fout.close();
    return 0;
}