Cod sursa(job #3309104)

Utilizator CatalinPangaleanuCatalin Pangaleanu CatalinPangaleanu Data 1 septembrie 2025 03:53:19
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <fstream>
#include <vector>
#include <algorithm>

int getFenwickDelta(int index)
{
    return (index ^ (index - 1)) & index;
}

std::pair<int, int> queryFenwickTree(const std::vector<std::pair<int, int>> &fenwickTree, int index)
{
    if (index < 0)
        return {0, -1};

    std::pair<int, int> result = fenwickTree[index];

    for (; index > 0; index -= getFenwickDelta(index))
    {
        if (fenwickTree[index].first > result.first)
            result = fenwickTree[index];
    }

    if (fenwickTree[0].first > result.first)
        result = fenwickTree[0];

    return result;
}

void updateFenwickTree(std::vector<std::pair<int, int>> &fenwickTree, int index, std::pair<int, int> value)
{
    fenwickTree[index] = value;

    if (index == 0)
        return;

    for (; index < fenwickTree.size(); index += getFenwickDelta(index))
    {
        if (value.first > fenwickTree[index].first)
            fenwickTree[index] = value;
    }
}

int main()
{
    std::ifstream inFile;
    inFile.open("scmax.in");

    int n;
    inFile >> n;

    std::vector<int> numbers(n), sortedNumbers(n);

    for (int i = 0; i < n; ++i)
    {
        inFile >> numbers[i];

        sortedNumbers[i] = numbers[i];
    }

    inFile.close();

    std::sort(sortedNumbers.begin(), sortedNumbers.end());
    auto endIt = std::unique(sortedNumbers.begin(), sortedNumbers.end());
    sortedNumbers.erase(endIt, sortedNumbers.end());

    std::vector<int> sortedIndex(n);

    for (int i = 0; i < n; ++i)
    {
        sortedIndex[i] = (int) (std::lower_bound(sortedNumbers.begin(), sortedNumbers.end(), numbers[i]) - sortedNumbers.begin());
    }

    std::vector<std::pair<int, int>> fenwickTree(sortedNumbers.size(), {0, -1});
    std::vector<int> bestLength(sortedNumbers.size()), previous(sortedNumbers.size());

    for (int i = 0; i < n; ++i)
    {
        std::pair<int, int> result = queryFenwickTree(fenwickTree, sortedIndex[i] - 1);

        if (result.first + 1 > bestLength[sortedIndex[i]])
        {
            bestLength[sortedIndex[i]] = result.first + 1;
            previous[sortedIndex[i]] = result.second;

            updateFenwickTree(fenwickTree, sortedIndex[i], {result.first + 1, sortedIndex[i]});
        }
    }

    int endIndex = (int) (std::max_element(bestLength.begin(), bestLength.end()) - bestLength.begin());

    std::vector<int> indexPath;
    indexPath.push_back(endIndex);

    while (previous[indexPath.back()] != -1)
    {
        indexPath.push_back(previous[indexPath.back()]);
    }

    std::ofstream outFile;
    outFile.open("scmax.out");

    outFile << bestLength[indexPath.front()] << '\n';

    for (int i = (int) indexPath.size() - 1; i >= 0; --i)
    {
        outFile << sortedNumbers[indexPath[i]] << ' ';
    }

    outFile.close();

    return 0;
}