Cod sursa(job #542930)

Utilizator AndrewTheGreatAndrei Alexandrescu AndrewTheGreat Data 27 februarie 2011 11:25:02
Problema Subsir crescator maximal Scor 55
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

const int nmax = 100100;
int Aib[nmax], A[nmax], N, s[nmax], unde[nmax], bst[nmax], bstmax;

struct cmp
{
    bool operator()(const int &a, const int &b)const
    {
        if(A[a] != A[b])
            return A[a] < A[b];
        return a < b;
    }
};

void read()
{
    freopen ("scmax.in","r",stdin);
    freopen ("scmax.out","w",stdout);
    int i;
    scanf("%d",&N);
    for(i = 1; i <= N; i++)
    {
        scanf("%d",&A[i]);
        s[i] = i;
    }

    sort(s + 1, s + N + 1, cmp());

    for(i = 1; i <= N; i++)
        unde[s[i]] = i;
}

inline int zeroz(int x)
{
    return x & -x;
}

void add(int inc, int val)
{
    while(inc <= N)
    {
        if(bst[val] > bst[Aib[inc]])
            Aib[inc] = val;
        inc += zeroz(inc);
    }
}

int maxim(int inc)
{
    int fin = 0;
    while(inc > 0)
    {
        if(bst[Aib[inc]] > bst[fin])
            fin = Aib[inc];
        inc -= zeroz(inc);
    }
    return fin;
}

void solve()
{
    int i;
    for(i = 1; i <= N; i++)
    {
        bst[i] = bst[maxim(unde[i] - 1)] + 1;
        if(bst[i] > bstmax)
            bstmax = bst[i];
        add(unde[i], i);
    }
}

void ecrire()
{
    int i = 0;
    printf("%d\n",bstmax);
    bstmax = 1;
    while(i <= N)
    {
        if(bst[i] == bstmax)
        {
            printf("%d ", A[i]);
            bstmax++;
        }
        i++;
    }
}

int main()
{
    read();
    solve();
    ecrire();
    return 0;
}