Cod sursa(job #1101539)

Utilizator 2dorTudor Ciurca 2dor Data 8 februarie 2014 17:33:32
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>
using namespace std;

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

const int MAXN = 100005;
int lung[MAXN];//lung[i] = indicele elementului maxim cu care putem forma sir de lungime i
int poz[MAXN];//poz[i] = indicele urmatorului element din subsirul crescator maximal din care face parte v[i]
int v[MAXN], N, sol;

void Read() {
    fin >> N;
    for (int i = 1; i <= N; ++i)
        fin >> v[i];
}

void BinSearch(int poznr) {
    int Left = 1; int Right = sol; int Middle;
    while (Right - Left > 1) {
        Middle = (Right - Left) / 2 + Left;
        if (v[lung[Middle]] > v[poznr])
            Left = Middle;
        else
            Right = Middle;
    }
    if (v[lung[Right]] > v[poznr]) {
        if (v[lung[Right + 1]] < v[poznr]) {
            lung[Right + 1] = poznr;
            poz[poznr] = lung[Right];
            ++sol;
        }
    }else if (v[lung[Left]] > v[poznr]) {
        lung[Right] = poznr;
        poz[poznr] = lung[Left];
    }
    if (v[lung[1]] < v[poznr]) {
        lung[1] = poznr;
        poz[poznr] = 0;
    }
}

void Solve() {
    lung[1] = N;
    sol = 1;
    for (int i = N - 1; i; --i)
        BinSearch(i);
}

void Write() {
    fout << sol << '\n';
    int nrpoz = lung[sol];
    for (int i = 0; i < sol; ++i) {
        fout << v[nrpoz] << ' ';
        nrpoz = poz[nrpoz];
    }
}

int main() {
    Read();
    Solve();
    Write();
    fin.close();
    fout.close();
    return 0;
}