Cod sursa(job #3191184)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 8 ianuarie 2024 23:48:41
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.73 kb
#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define all(v) (v).begin(), (v).end()
#define pb push_back
using namespace std;
ifstream fin("scmax.in");
ofstream fout("scmax.out");

const int N = 1e5 + 9;
int n, a[N];

using vi = vector<int>;

int mem[N], t[N];
int aib[N];
void update(int p, int i)
{
    for(; p <= n; p += p & -p)
        if(mem[aib[p]] < mem[i])
            aib[p] = i;
}
int query(int p)
{
    int i = 0;
    for(; p; p -= p & -p)
        if(mem[i] < mem[aib[p]])
            i = aib[p];
    return i;
}

vi v;
int get_idx(int val)
{
    return distance(v.begin(), lower_bound(all(v), val)) + 1;
}


const int Lim = 5000;
char s[Lim];
int p = Lim - 1;

void next()
{
    if(++p == Lim)
    {
        //fread(s, 1, Lim, fin);
        fin.get(s, Lim + 1, EOF);
        p = 0;
    }
}

void get(int& x)
{
    while(s[p] != '-' && !isdigit(s[p]))next();\

    int semn = 1;
    if(s[p] == '-')
    {
        semn = -1;
        next();
    }

    for(x = 0;isdigit(s[p]); next())
        x = x * 10 + s[p] - '0';

    x *= semn;
}

int main()
{
    get(n);

    FOR(i, 1, n)get(a[i]);

    reverse(a + 1, a + n + 1);

    FOR(i, 1, n)v.pb(a[i]);
    sort(all(v));
    v.erase(unique(all(v)), v.end());

    FOR(i, 1, n)a[i] = get_idx(a[i]);

    int ans = 0;
    FOR(i, 1, n)
    {
        t[i] = query(n - a[i]);
        mem[i] = mem[query(n - a[i])] + 1;
        ans = max(ans, mem[i]);
        update(n - a[i] + 1, i);
    }

    fout << ans << '\n';
    vi sir;
    FOR(i, 1, n)
        if(mem[i] == ans)
        {
            for(; i; i = t[i])fout << v[a[i] - 1] << ' ';
            break;
        }

    return 0;
}