Cod sursa(job #2884176)

Utilizator gripzStroescu Matei Alexandru gripz Data 2 aprilie 2022 15:16:48
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <iostream>
#include <algorithm>

#define NMAX 100004

using namespace std;

struct nod {
    int val;
    int P;
};

int N, a[NMAX], a2[NMAX], a3[NMAX], d[NMAX], p[NMAX], S, E;
int val, pos, P;
nod T[4 * NMAX];

void update(int node, int st, int dr) {
    if(st == dr) {
        if(val > T[node].val) {
            T[node].val = val;
            T[node].P = P;
        }
    } else {
        int mid = (st + dr) / 2;

        if(pos <= mid) {
            update(2 * node, st, mid);
        } else {
            update(2 * node + 1, mid + 1, dr);
        }
        if(T[2 * node].val > T[2 * node + 1].val) {
            T[node] = T[2 * node];
        } else {
            T[node] = T[2 * node + 1];
        }

    }
}

void query(int node, int st, int dr) {
    if(S <= st && dr <= E) {
        if(T[node].val > val) {
            val = T[node].val;
            P = T[node].P;
        }
    } else {
        int mid = (st + dr) / 2;
        if(S <= mid) {
            query(2 * node, st, mid);
        }
        if(E > mid) {
            query(2 * node + 1, mid + 1, dr);
        }
    }
}

int cb(int val) {
    int st = 0, dr = N, mid, last;
    while(st <= dr) {
        mid = (st + dr) / 2;
        if(val <= a2[mid]) {
            last = mid;
            dr = mid - 1;
        } else {
            st = mid + 1;
        }
    }

    return last;
}

int main()
{
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);

    cin >> N;
    for(int i = 1; i <= N; i++) {
        cin >> a[i];
        a3[i] = a[i];
        a2[i] = a[i];
    }

    sort(a2 + 1, a2 + N + 1);
    for(int i = 1; i <= N; i++) {
        a[i] = cb(a[i]);
    }

    int maxPos = 1;
    for(int i = 1; i <= N; i++) {
        S = 1;
        E = a[i] - 1;
        val = -1;
        P = 0;
        if(E > 0)
            query(1, 1, N);
        else
            val = 0;
        d[i] = 1 + val;
        p[i] = P;
        if(d[maxPos] < d[i]) {
            maxPos = i;
        }

        val = d[i];
        P = i;
        pos = a[i];
        update(1, 1, N);
    }

    cout << d[maxPos] << endl;
    pos = maxPos;

    int a4[NMAX], L = 0;

    do {
        L++;
        a4[L] = a3[pos];
        pos = p[pos];
    }
    while(pos != 0);

    for(int i = L; i > 0; i--) {
        cout << a4[i] << " ";
    }

    return 0;
}