Cod sursa(job #2565918)

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

#define MAXN    100005

#define FILENAME    std::string("scmax")
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;
void normalize() {
    std::sort(norm.begin(), norm.end());
    for (int i=0; i<N; ++i)
        V[-norm[i].second] = i+1, rev[i+1] = norm[i].first;
}

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] = left; 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 idx) {
    if (DP[idx] != 1) print(prev[idx]);
    output << rev[idx] << ' ';
}

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

    return 0;
}