Cod sursa(job #2951201)

Utilizator Pop_EmilPal Tamas Pop_Emil Data 5 decembrie 2022 17:58:29
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <stdio.h>
#include <map>
#include <algorithm>

using namespace std;

#define NMax 100005

FILE *in = fopen("scmax.in", "r"), *out = fopen("scmax.out", "w");

int N;
int a[NMax], comp[NMax], BIT[NMax] = {0}, res[NMax], origid[NMax], pre[NMax], lengths[NMax];
map<int, int> comp_mapping, rev_comp_mapping;

int query(int index){
    int ML_pos = 0, i = index;
    while (i > 0){
        if (BIT[i] > BIT[ML_pos])
            ML_pos = i;
        i = i - (i & (-i));
    }
    return ML_pos;
}

int main()
{
    // Read array
    fscanf(in, "%d", &N);
    for (int i = 1; i <= N; ++i){
        fscanf(in, "%d", &a[i]);
        comp[i] = a[i];
    }

    // Coordinate compression
    sort(comp + 1, comp + N + 1);
    int j = 1;
    for (int i = 1; i <= N; ++i){
        if(i >= 2 && comp[i] == comp[i-1])
            continue;
        comp_mapping[comp[i]] = j;
        rev_comp_mapping[j] = comp[i];
        ++j;
    }
    for (int i = 1; i <= N; ++i){
        comp[i] = comp_mapping[a[i]];
    }

    // Construct BIT of max lengths
    int ML_pos;
    for (int i = 1; i <= N; ++i){
        // Get max length up until now (?)
        ML_pos = query(comp[i] - 1);
        pre[i] = origid[ML_pos];
        lengths[i] = BIT[ML_pos] + 1;
        // Update nodes of BIT
        j = comp[i];
        while(j <= N){
            if (BIT[ML_pos] + 1 > BIT[j]) {
                BIT[j] = BIT[ML_pos] + 1;
                origid[j] = i;
            }
            j = j + (j & (-j));
        }

    }

    // Get max increasing subsequence length
    int pos_max_length = 0;
    for (int i = 1; i <= N; ++i){
        if (lengths[i] > lengths[pos_max_length])
            pos_max_length = i;
    }
    fprintf(out, "%d\n", lengths[pos_max_length]);

    // Get one such subsequence
    j = 1;
    for(int i = pos_max_length; i >= 1; i = pre[i], ++j){
        res[j] = rev_comp_mapping[comp[i]];
    }
    for (int k = j - 1; k >= 1; --k)
        fprintf(out, "%d ", res[k]);

    return 0;
}