Cod sursa(job #489314)

Utilizator purdea.andreiPurdea Andrei purdea.andrei Data 2 octombrie 2010 11:35:30
Problema Subsir crescator maximal Scor 20
Compilator c Status done
Runda Arhiva educationala Marime 2.87 kb
/* 1:40 so far */
#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[*((int *)a)] - X[*((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 */

#define DEBUG(x) if (0) { fprintf(stderr, x); fflush(stderr); }

int ZEROS(int num) {
    if (num==0) DEBUG("Wierd, num is zero!\n");
    int z = 0;
    while ((num & 1) == 0) {
        ++z;
        num>>=1;
    }
    return z;
}

int getmax(int order) { /* order can be 1 at the smallest */
    if (order==0) return 0;
    int max = A[order];
    do {
        order -= order ^ (order - 1);
        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 += order ^ (order-1);
        DEBUG(",\n");
    }
}

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

int temp[100010];

void merges(int * a, int i, int j) {
    int k, l, x, m;
    if (i>=j) return;
    m = (i + j) / 2;
    merges(a, i, m);
    merges(a, m+1, j);
    k = i;
    l = m + 1;
    x = i;
    while (k<=m || l<=j) {
        if (k<=m &&  l<=j) {
            if (X[a[k]] < X[a[l]]) {
                temp[x] = a[k];
                x++; k++;
            } else {
                temp[x] = a[l];
                x++; l++;
            }
        } else if (k<=m) {
            temp[x] = a[k];
            x++; k++;
        } else {
            temp[x] = a[l];
            x++; l++;
        }
    }
    for (x = i; x<=j; ++x) a[x] = temp[x];
}

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]);
        smallest_tail[i] = -1;
    }
    smallest_tail[n] = -1;
    for (i=0;i<n;++i) S[i]=i;
    /*qsort(S, n, sizeof(int), sortme);*/
    merges(S, 0, n-1);

    for (i=0;i<n;++i) SS[S[i]] = i;
/*    printf("S: "); for (i=0;i<n;i++) printf("%d ", S[i]);
    printf("\nSS: "); for (i=0;i<n;i++) printf("%d ", SS[i]);
    printf("\n");*/
    
    
    for (i=0;i<n;++i) {
        int temp = SS[i] - 1;
        int l;
        while (temp>=0 && X[S[temp]]==X[i]) temp--;
        l = getmax(temp+1);
        P[i] = smallest_tail[l];
        /*printf("l:%d %d %d %d %d\n", i, X[i], l, P[i], temp);*/
        add(SS[i]+1, l + 1);
        if (smallest_tail[l+1] == -1 || X[i]<X[smallest_tail[l+1]]) smallest_tail[l+1] = i;
    }
    printf("%d\n", getmax(n));
    backwrite(smallest_tail[getmax(n)]);
    printf("\n");
    return 0;
}