Cod sursa(job #2949065)

Utilizator matei.tudoseMatei Tudose matei.tudose Data 29 noiembrie 2022 17:15:18
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#include <algorithm>
#include <cmath>
#include <stack>
using namespace std;

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

struct elem
{
    int lungMax, nod;
} BIT[100005];

stack<int> ansStack;
int n, numbers[100005], indexes[100005], tata_de[100005];

int getLSB(int x)
{
    return (x & (-x));
}

void setValue(int x, int poz)
{
    int cPoz = poz;
    for (; cPoz <= n; cPoz += getLSB(cPoz))
    {
        if (BIT[cPoz].lungMax < x)
        {
            BIT[cPoz].lungMax = x;
            BIT[cPoz].nod = poz;
        }
    }
}

elem getValue(int poz)
{
    int pivot = poz + 1;
    elem ans = {0, 0};
    for (; poz > 0; poz -= getLSB(poz))
    {
        if (ans.lungMax < BIT[poz].lungMax && numbers[pivot] > numbers[BIT[poz].nod])
            ans = BIT[poz];
    }
    return ans;
}

bool compareIndexes(int x, int y)
{
    if (numbers[x] == numbers[y])
        return x < y;
    return numbers[x] < numbers[y];
}

int main()
{
    fin >> n;
    for (int i = 1; i <= n; i++)
    {
        fin >> numbers[i];
        indexes[i] = i;
        if (i > 1 && numbers[i] == numbers[i - 1])
            i--, n--;
    }
    sort(indexes + 1, indexes + 1 + n, compareIndexes);
    for (int i = 1; i <= n; i++)
    {
        if (i == 1)
        {
            setValue(1, indexes[i]);
            continue;
        }
        elem ans = getValue(indexes[i] - 1);
        tata_de[indexes[i]] = ans.nod;
        setValue(ans.lungMax + 1, indexes[i]);
    }
    numbers[n + 1] = INT32_MAX;
    elem ans = getValue(n);
    fout << ans.lungMax << "\n";
    int header = ans.nod;
    while (header)
    {
        ansStack.push(numbers[header]);
        header = tata_de[header];
    }
    while (!ansStack.empty())
    {
        fout << ansStack.top() << " ";
        ansStack.pop();
    }
    fout << "\n";
    return 0;
}