Cod sursa(job #2726001)

Utilizator preda.andreiPreda Andrei preda.andrei Data 20 martie 2021 00:01:25
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include <algorithm>
#include <fstream>
#include <tuple>
#include <vector>

using namespace std;

class Fenwick {
public:
    Fenwick(int size) : values_(size + 1, 0), indices_(size + 1, -1) {
    }

    void Update(int pos, int value, int index) {
        while (pos < (int)values_.size()) {
            if (value > values_[pos]) {
                values_[pos] = value;
                indices_[pos] = index;
            }
            pos += Lsb(pos);
        }
    }

    pair<int, int> Max(int pos) const {
        auto best_pos = 0;

        while (pos > 0) {
            if (values_[pos] > values_[best_pos]) {
                best_pos = pos;
            }
            pos -= Lsb(pos);
        }
        return {values_[best_pos], indices_[best_pos]};
    }

private:
    static int Lsb(int num) {
        return num & -num;
    }

    vector<int> values_;
    vector<int> indices_;
};

vector<int> Distinct(vector<int> vec) {
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
    return vec;
}

int Pos(int num, const vector<int>& vec) {
    return lower_bound(vec.begin(), vec.end(), num) - vec.begin();
}

vector<int> ExtractSequence(const vector<int>& vec,
                            const vector<int>& prev,
                            int index) {
    vector<int> res;
    while (index >= 0) {
        res.push_back(vec[index]);
        index = prev[index];
    }
    reverse(res.begin(), res.end());
    return res;
}

int main() {
    ifstream fin("scmax.in");
    ofstream fout("scmax.out");

    int n;
    fin >> n;

    vector<int> vec(n);
    for (auto& num : vec) {
        fin >> num;
    }

    auto distinct = Distinct(vec);
    Fenwick count(distinct.size());

    vector<int> prev(n, -1);
    int max_length = 0;
    int max_index = 0;

    for (int i = 0; i < n; i += 1) {
        int pos = Pos(vec[i], distinct) + 1;
        int left_length;
        tie(left_length, prev[i]) = count.Max(pos - 1);

        count.Update(pos, left_length + 1, i);
        if (left_length + 1 > max_length) {
            max_length = left_length + 1;
            max_index = i;
        }
    }

    auto res = ExtractSequence(vec, prev, max_index);
    fout << res.size() << "\n";
    for (const auto& num : res) {
        fout << num << " ";
    }
    fout << "\n";

    return 0;
}