Cod sursa(job #255210)

Utilizator Mishu91Andrei Misarca Mishu91 Data 8 februarie 2009 20:39:13
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.3 kb
#include <cstdio>
#include <algorithm>

using namespace std;

#define MAX_N 100005
#define lsb(x) (x & -x)

int V[MAX_N], N, A[MAX_N], S[MAX_N], D[MAX_N], Ant[MAX_N], AIB[MAX_N];

void citire()
{
    scanf("%d",&N);

    for(int i = 1; i <= N; ++i)
    {
        scanf("%d",V+i);
        A[i] = S[i] = V[i];
    }
}

void norm()
{
    sort(A+1, A+N+1);

    int Nr = 1;
    for(int i = 2; i <= N; ++i)
        if(A[i] != A[Nr])
            A[++Nr] = A[i];

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

void update(int x, int val)
{
    for(; x <= N; x += lsb(x))
        if(D[val] > D[AIB[x]])
            AIB[x] = val;
}

int query(int x)
{
    int rez = 0;
    for(; x > 0; x -= lsb(x))
        if(D[AIB[x]] > D[rez])
            rez = AIB[x];
    return rez;
}

void solve()
{
    for(int i = 1; i <= N; ++i)
    {
        Ant[i] = query(S[i] - 1);
        D[i] = D[Ant[i]] + 1;
        update(S[i], i);
    }

    int bst = 0;
    for(int i = 1; i <= N; ++i)
        if(D[i] > D[bst])
            bst = i;
    printf("%d\n",D[bst]);

    int Nr = 0;
    for(int i = bst; i; i = Ant[i])
        S[++Nr] = V[i];
    for(;Nr; --Nr)
        printf("%d ",S[Nr]);
}

int main()
{
    freopen("scmax.in","rt",stdin);
    freopen("scmax.out","wt",stdout);

    citire();
    norm();
    solve();
}