Cod sursa(job #902869)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 1 martie 2013 17:06:14
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include <cstdio>
#include <cstring>
#include <cassert>

#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <map>

using namespace std;

typedef long long LL;
typedef vector<int>::iterator it;

const int oo = 2000000001;
const int MAX_N = 100005;

int N, Values[MAX_N], Length[MAX_N], Father[MAX_N];
int MinValue[MAX_N], LIS;

int Search(int Value) {
    int Left = 1, Right = N, Position = 0;
    while (Left <= Right) {
        int Middle = (Left + Right) / 2;
        if (Values[MinValue[Middle]] < Value)
            Left = Middle + 1, Position = Middle;
        else
            Right = Middle - 1;
    }
    return MinValue[Position];
}

void Initialize() {
    Values[0] = -oo, Values[N + 1] = oo;
    MinValue[0] = 0;
    for (int i = 1; i <= N; ++i)
        MinValue[i] = N + 1;
    LIS = 0;
}

void Solve() {
    Initialize();
    for (int i = 1; i <= N; ++i) {
        Father[i] = Search(Values[i]);
        Length[i] = Length[Father[i]] + 1;
        if (Values[i] < Values[MinValue[Length[i]]])
            MinValue[Length[i]] = i;
        if (Length[i] > Length[LIS])
            LIS = i;
    }
}

void Read() {
    assert(freopen("scmax.in", "r", stdin));
    assert(scanf("%d", &N) == 1);
    for (int i = 1; i <= N; ++i)
        assert(scanf("%d", &Values[i]) == 1);
}

void Trace(int P) {
    if (P == 0)
        return;
    Trace(Father[P]);
    printf("%d ", Values[P]);
}

void Print() {
    assert(freopen("scmax.out", "w", stdout));
    printf("%d\n", Length[LIS]);
    Trace(LIS);
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}