Cod sursa(job #2983085)

Utilizator gripzStroescu Matei Alexandru gripz Data 21 februarie 2023 16:44:44
Problema Subsir crescator maximal Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.53 kb
#include <iostream>
#include <algorithm>
#include <vector>

#define NMAX 100003

using namespace std;

int N, v[NMAX], s[NMAX], vn[NMAX], L = 1, pre[NMAX];
int S, E, val, pos;
pair<int, int> T[4 * NMAX];

int cb(int x) {
    int st = 1, dr = L, mid, last;
    while(st <= dr) {
        mid = (st + dr) / 2;
        if(x > s[mid]) {
            st = mid + 1;
        } else {
            last = mid;
            dr = mid - 1;
        }
    }

    return last;
}

void normalize() {
    memcpy(s, v, sizeof(v));
    sort(s + 1, s + 1 + N);

    for(int i = 2; i <= N; i++) {
      if(s[i] != s[L]) {
        s[++L] = s[i];
      }
    }

    for(int i = 1; i <= N; i++) {
        vn[i] = cb(v[i]);
       // cout << vn[i] << " ";
    }
}

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

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

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

    cin >> N;
    for(int i = 1; i <= N; i++)
        cin >> v[i];

    normalize();

    int best = 0, bestPos = 0;
    for(int i = 1; i <= N; i++) {
        /*for(int j = 1; j < vn[i]; j++) {
            best[vn[i]] = max(best[vn[i]], 1 + best[j]);
        }*/
        S = 1;
        E = vn[i] - 1;
        val = 0;
        if(S <= E) {
            query(1, 1, N);
            pre[vn[i]] = pos;
        }

        val += 1;

        if(best < val) {
            best = val;
            bestPos = vn[i];
        }

        pos = vn[i];
        update(1, 1, N);
    }

    cout << best << endl;
    vector<int> R;
    for(int i = 1; i <= best; i++) {
        R.push_back(s[bestPos]);
        bestPos = pre[bestPos];
    }

    for(int i = R.size() - 1; i >= 0; i--) {
        cout << R[i] << " ";
    }

    return 0;
}