Cod sursa(job #542937)

Utilizator AndrewTheGreatAndrei Alexandrescu AndrewTheGreat Data 27 februarie 2011 11:35:10
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.62 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 = N;
    printf("%d\n",bstmax);
    int temp = bstmax;
    while(i > 0)
    {
        if(bst[i] == bstmax)
        {
            unde[bstmax] = A[i];
            bstmax--;
        }
        i--;
    }

    for(i = 1; i <= temp; i++)
        printf("%d ",unde[i]);
}

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