Cod sursa(job #470311)

Utilizator purdea.andreiPurdea Andrei purdea.andrei Data 13 iulie 2010 09:24:29
Problema Subsir crescator maximal Scor 5
Compilator c Status done
Runda Arhiva educationala Marime 1.63 kb
#include <stdio.h>
#include <stdlib.h>

int n;
int X[100010];
int S[100010]; // X[S[i]] e array-ul sortat

int sortme(const void * a, const void * b) {
    return X[S[*((int *)a)]] - X[S[*((int*)b)]];
}

int SS[100010]; // SS[i] e pozitia lui X[i] in arrayul sortat
int smallest_tail[100010];


int P[100010]; // P[i] = elementul anterior elementului cu indicele i, pentru scrierea rezultatelor

int A[100010]; // arbore indexat binar, contine lungimea maxima care se poate poate atinge doar cu elemente de valoare

int ZEROS(int num) {
    int z = 0;
    while (num & 1 == 0) {
        ++z;
        num>>=1;
    }
    return z;
}

int getmax(int order) {
    int max = A[order];
    do {
        order -= 1 << ZEROS(order);
        if (order>=0 && A[order]>max) max = A[order];
    } while (order>=0);
    return max;
}

void add(int order, int mod) {
    while (order<n) {
        if (A[order]<mod) A[order] = mod;
        order += 1 << ZEROS(order);
    }
}

void backwrite(int lp, int l) {
    if (l>0) {
        backwrite(P[lp], l-1);
        printf("%d ", X[lp]);
    }
}

int main() {
    int i;
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);
    scanf("%d", &n);
    for (i=0;i<n;++i) {
        scanf("%d", &X[i]);
    }
    for (i=0;i<n;++i) S[i]=i;
    qsort(S, n, sizeof(int), sortme);
    for (i=0;i<n;++i) SS[S[i]] = i;

    for (i=0;i<n;++i) {
        int l = getmax(SS[i]-1);
        P[i] = smallest_tail[l];
        add(SS[i], l + 1);
        if (X[i]<X[smallest_tail[l+1]]) smallest_tail[l+1] = i;
    }
    printf("%d\n", getmax(n-1));
    backwrite(smallest_tail[getmax(n-1)], getmax(n-1));
    printf("\n");
    return 0;
}