Cod sursa(job #998449)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 17 septembrie 2013 01:18:10
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 kb
#include <fstream>
#include <algorithm>

using namespace std;

const int MAX_N = 100002;

int N, Max, K;
int v[MAX_N], a[MAX_N], F[MAX_N], sol[MAX_N];
pair < int, int > A[MAX_N];

inline void Update(int pos, pair < int, int > val) {
    for( ; pos <= N; pos += pos^(pos&(pos-1))) {
        if(val.first  > A[pos].first)
            A[pos] = val;
    }
}

inline pair < int, int > Query(int pos) {
    pair < int, int > x;
    for( ; pos > 0; pos -= pos^(pos&(pos-1)))
        if(A[pos].first > x.first)
            x = A[pos];
    return x;
}

inline int bs(int x) {
    int l = 1, r = K, m = 0;
    while(l <= r) {
        m = (l+r)/2;
        if(a[m] < x)
            l = m+1;
        else if(a[m] > x)
            r = m-1;
        else return m;
    }
    return 0;
}

int main() {
    ifstream f("scmax.in");
    ofstream g("scmax.out");

    f >> N;
    for(int i = 1; i <= N; ++i) {
        f >> v[i];
        a[i] = v[i];
    }

    sort(a+1, a+N+1);
    K = 1;
    for(int i = 2; i <= N; ++i) {
        if(a[i] != a[K])
            a[++K] = a[i];
    }

    int temp = 0;
    pair < int, int > p;
    for(int i = 1, x; i <= N; ++i) {
        x = bs(v[i]);
        p = Query(x-1);
        ++p.first;
        Update(x, make_pair(p.first, i));
        if(p.first > Max)
            Max = p.first, temp = i;
        F[i] = p.second;
    }

    for(int i = Max; i; --i) {
        sol[i] = v[temp];
        temp = F[temp];
    }

    g << Max << "\n";
    for(int i = 1; i <= Max; ++i)
        g << sol[i] << " ";
    g << "\n";

    f.close();
    g.close();

    return 0;
}