Cod sursa(job #3165238)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 5 noiembrie 2023 18:21:41
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.33 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

ifstream f("scmax.in");
ofstream g("scmax.out");

static constexpr int NMAX = (int)(1e5 + 1);

int n;
vector<int> v;

vector<int> no_duplicates;

int dp[NMAX];

namespace InParser
{
    static constexpr int BSIZE = (1 << 16);

    static int pos = (BSIZE - 1);
    static char buff[BSIZE];

    static inline char Char()
    {
        ++pos;

        if (pos == BSIZE)
        {
            pos = 0;

            int n = fread(buff, 1, BSIZE, stdin);
            if (n != BSIZE)
                for (int i = n; i < BSIZE; ++i)
                    buff[i] = 0;
        }

        return buff[pos];
    }

    inline int Int()
    {
        int ans = 0;

        for (;;)
        {
            char Ch = Char();

            if (Ch >= '0' && Ch <= '9')
            {
                ans = (int)(Ch - '0');
                break;
            }
        }

        for (;;)
        {
            char Ch = Char();

            if (Ch >= '0' && Ch <= '9')
                ans = ans * 10 + (int)(Ch - '0');
            else
                break;
        }

        return ans;
    }
};

static inline int normalize(vector<int> &V)
{
    vector<int> v = V;

    sort(v.begin(), v.end());

    vector<int> q = {v[0]};

    int n = (int)v.size();
    for (int i = 1; i < n; ++i)
        if (v[i] != v[i - 1])
            q.push_back(v[i]);

    no_duplicates = q;

    for (auto &it : V)
        it = (int)(lower_bound(q.begin(), q.end(), it) - q.begin()) + 1;

    return (int)q.size();
}

class FenwickTree
{
    static constexpr int NMAX = (int)(1e5);

    int n, a[NMAX];

    static inline int LSB(const int &X)
    {
        return ((X & (-X)));
    }

    static inline int my_max(const int &a, const int &b)
    {
        return ((a > b) ? a : b);
    }

public:
    FenwickTree(const int &elems)
    {
        n = elems;
        for (int i = 0; i <= n; ++i)
            a[i] = 0;
        return;
    }

    inline void update(const int &pos, const int &val)
    {
        for (int i = pos; i <= n; i += LSB(i))
            a[i] = my_max(a[i], val);

        return;
    }

    inline int query(const int &pos)
    {
        if (pos < 1)
            return 0;

        int ans = 0;
        for (int i = pos; i >= 1; i -= LSB(i))
            ans = my_max(ans, a[i]);

        return ans;
    }
};

static inline void read()
{
    f.tie(nullptr);

    f >> n;
    for (int i = 1; i <= n; ++i)
    {
        int x = 0;
        f >> x;

        v.push_back(x);
    }

    return;
}

static inline void reconstruct()
{
    int ans = 0, pos = 0;

    for (int i = 0; i < n; ++i)
        if (dp[i] > ans)
            ans = dp[i], pos = i;

    g << ans << '\n';

    if (!ans)
        return;

    vector<int> q = {v[pos]};
    --ans;

    for (int i = pos - 1; i >= 0 && ans; --i)
        if (v[i] < v[pos] && dp[i] == ans)
            q.push_back(v[i]), pos = i, --ans;

    reverse(q.begin(), q.end());

    for (int i = 0; i < (int)q.size(); ++i)
    {
        g << no_duplicates[q[i] - 1];

        if (i != (int)q.size() - 1)
            g << ' ';
        else
            g << '\n';
    }

    return;
}

int main()
{
    read();

    int max_value = normalize(v);

    FenwickTree t(max_value);

    for (int i = 0; i < n; ++i)
        dp[i] = 1 + t.query(v[i] - 1), t.update(v[i], dp[i]);

    reconstruct();

    return 0;
}