Cod sursa(job #2766951)

Utilizator EusebiudistrugatorulLionel Messi Eusebiudistrugatorul Data 4 august 2021 09:08:09
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <bits/stdc++.h>
#define Intro ios::sync_with_stdio(0), cin.tie(0)
#define ll long long
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");
int const N = 1e5 + 5;
vector<int> father(N), ordered_elements = {0}, max_length(N), tree(N);
unordered_map<int, int> pos;
unordered_set<int> unique_store;
int elements;

int query(int position) {
    int maximum = 0, max_pos = 0;
    while (position > 0) {
        if (maximum < max_length[position]) {
            maximum = max_length[position];
            max_pos = tree[position];
        }
        position -= position & -position;
    }
    return max_pos;
}

void update(int beginning, int maximum) {
    int max_pos = beginning - 1;
    while (beginning <= elements) {
        if (maximum > max_length[beginning]) {
            max_length[beginning] = maximum;
            tree[beginning] = max_pos;
        } else {
            maximum = max_length[beginning];
            max_pos = tree[beginning];
        }
        beginning += beginning & -beginning;
    }
}

int main() {
    fin >> elements;
    vector<int> unordered_elements(elements + 1);
    for (int i = 1; i <= elements; ++i) {
        fin >> unordered_elements[i];
        unique_store.insert(unordered_elements[i]);
        tree[i] = i;
    }
    int new_length = 1;
    for (int element : unique_store) {
        ordered_elements.push_back(element);
        new_length++;
    }
    sort(ordered_elements.begin(), ordered_elements.end());
    for (int i = 1; i < new_length; ++i) {
        pos[ordered_elements[i]] = i;
    }
    int last_pos = 1, maximum = 0;
    for (int i = 1; i <= elements; ++i) {
        int act_pos = pos[unordered_elements[i]];
        int act_max_pos = query(act_pos - 1);
        father[act_pos] = act_max_pos;
        max_length[act_pos] = max_length[act_max_pos] + 1;
        tree[act_pos] = act_pos;
        if (max_length[act_pos] > maximum) {
            maximum = max_length[act_pos];
            last_pos = act_pos;
        }
        update(act_pos + 1, max_length[act_pos]);
    }
    vector<int> scmax;
    fout << maximum << '\n';
    while (last_pos > 0 and maximum > 0) {
        scmax.push_back(ordered_elements[last_pos]);
        last_pos = father[last_pos];
        maximum--;
    }
    reverse(scmax.begin(), scmax.end());
    for (int element : scmax) {
        fout << element << ' ';
    }
    return 0;
}