Cod sursa(job #2565974)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 2 martie 2020 18:10:11
Problema Subsir crescator maximal Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.77 kb
#include <bits/stdc++.h>

#define MAXN    100005

#define FILENAME    std::string("euclid2")
std::ifstream input (FILENAME+".in");
std::ofstream output(FILENAME+".out");

int N;
int V[MAXN], rev[MAXN];
int DP[MAXN], prev[MAXN];
std::vector <std::pair <int, int>> norm;

int ST[4*MAXN];
#define LEFT   2*index
#define RIGHT  2*index+1
#define MIDDLE (left+right)/2
void update(int pos, int X, int left = 1, int right = N, int index = 1) {
    if (left == right) { ST[index] = X; return;}
    if (pos <= MIDDLE) update(pos, X, left, MIDDLE, LEFT);
    else               update(pos, X, MIDDLE+1, right, RIGHT);
    ST[index] = (DP[ST[LEFT]] > DP[ST[RIGHT]] ? ST[LEFT] : ST[RIGHT]);
}
int query(int A, int B, int left = 1, int right = N, int index = 1) {
    if (A <= left && right <= B) return ST[index];
    int max = -2e9, best = -1;
    if (A <= MIDDLE) {
        int v = query(A, B, left, MIDDLE, LEFT);
        if (max < DP[v]) max = DP[v], best = v;
    }
    if (MIDDLE <  B) {
        int v = query(A, B, MIDDLE+1, right, RIGHT);
        if (max < DP[v]) max = DP[v], best = v;
    }   return best;
}

void print(int len, int from = N) {
    for (int i=from; i>0; --i) {
        if (DP[i] == len) {
            if (len > 1) print(len-1, i-1);
            output << V[i] << ' ';
            i = 0;
        }
    }
}

int main()
{
    input >> N;
    for (int i=1; i<=N; ++i) input >> V[i], norm.push_back({V[i], -i});
    std::sort(norm.begin(), norm.end());
    int max = 0;
    for (int i=0; i<N; ++i) {
        int idx = -norm[i].second;
        prev[idx] = query(1, idx);
        DP[idx] = DP[prev[idx]]+1;
        update(idx, idx);
        if (DP[idx] > max) max = DP[idx];
    }   output << max << '\n';
    print(max);

    return 0;
}