Cod sursa(job #2476241)

Utilizator Savu_Stefan_CatalinSavu Stefan Catalin Savu_Stefan_Catalin Data 18 octombrie 2019 15:04:53
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

const int BSIZE = (1 << 16), NMAX = 1e5 + 5;

int N, A[NMAX], B[NMAX], V[NMAX], M, S[NMAX], AIB[NMAX], Max, p;
int dp[NMAX];

vector < int > Pozitii;

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

static inline void Update (int pos, int val)
{
    for(int i = pos; i <= M; i += UB(i))
        AIB[i] = max(AIB[i], val);

    return;
}

static inline int Query (int pos)
{
    int r = 0;

    for(int i = pos; i >= 1; i -= UB(i))
        r = max(r, AIB[i]);

    return r;
}

///
int pos = BSIZE - 1;
char buff[BSIZE];

static inline char Char ()
{
    ++pos;

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

        fread(buff, 1, BSIZE, stdin);
    }

    return buff[pos];
}

static inline int Int ()
{
    int r = 0;

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

        if(isdigit(ch))
        {
            r = (ch - '0');

            break;
        }
    }

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

        if(isdigit(ch))
            r = r * 10 + (ch - '0');
        else break;
    }

    return r;
}
///

static inline void Read ()
{
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);

    N = Int();

    for(int i = 1; i <= N; ++i)
        S[i] = B[i] = A[i] = Int();

    return;
}

static inline void Normalizare ()
{
    sort(B + 1, B + N + 1);

    V[++M] = B[1];
    for(int i = 2; i <= N; ++i)
        if(B[i] != B[i - 1])
            V[++M] = B[i];

    for(int i = 1; i <= N; ++i)
        S[i] = (lower_bound(V + 1,V + M +1, S[i]) - V);

    return;
}

static inline void CMLSC ()
{
    for(int i = 1; i <= N; ++i)
    {
        dp[i] = Query(S[i] - 1) + 1;

        Update(S[i], dp[i]);
    }

    return;
}

int main()
{
    Read();

    Normalizare();

    CMLSC();

    for(int i = 1; i <= N; ++i)
        if(dp[i] > Max)
        {
            Max = dp[i];

            p = i;
        }

    printf("%d\n", Max);

    Pozitii.push_back(p);

    for(int i = p - 1; i >= 1; --i)
        if(A[i] < A[p] && dp[i] == dp[p] - 1)
        {
            Pozitii.push_back(i);

            p = i;
        }

    for(int i = Max - 1; i >= 0; --i)
        printf("%d ", A[Pozitii[i]]);

    printf("\n");

    return 0;
}