Cod sursa(job #1516400)

Utilizator theprdvtheprdv theprdv Data 2 noiembrie 2015 23:30:35
Problema Subsir crescator maximal Scor 70
Compilator c Status done
Runda Arhiva educationala Marime 1.83 kb
/* Binary indexed tree solution */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

#define MAXN 100005
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define lastSB(x) (x & -x)

int N, A[MAXN], P[MAXN], T[MAXN], max, idx;

struct pw{
    int idx, max;
} BIT[MAXN];

void Qsort(int l, int r)
{
    if (l >= r) return;

    int i = l, j = r, rd = l + rand() % (r - l + 1), piv_idx = P[rd],
        pivot = A[P[rd]], aux;

    while(i < j)
    {
        while(A[P[i]] < pivot || (pivot == A[P[i]] && P[i] > piv_idx )) ++i;
        while(A[P[j]] > pivot || (pivot == A[P[j]] && P[j] < piv_idx )) --j;

         if(i <= j)
        {
            aux = P[i], P[i] = P[j], P[j] = aux;
            ++i, --j;
        }
    }

    Qsort(l, j);
    Qsort(i, r);
}

int query(int idx)
{
    int max = 0, i = 0;
    for (; idx; idx -= lastSB(idx))
        if (BIT[idx].max > max)
            max = BIT[idx].max, i = BIT[idx].idx;

    return i;
}

void update(int idx, int max)
{
    int i = idx;
    for (; i <= N; i += lastSB(i))
        if (BIT[i].max < max)
            BIT[i].max = max, BIT[i].idx = idx;
}

int main()
{
    srand(time(NULL));

    assert(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]),
        P[i] = i;

    Qsort(1, N);

    for (i = 1; i <= N; ++i)
    {
        int before = query(P[i]);
        T[P[i]] = before;
        update(P[i], BIT[before].max + 1);

        if (BIT[before].max + 1 > max)
            max = BIT[before].max + 1,
            idx = P[i];
    }

    printf("%d\n", max);

    for (i = max; i; P[i--] = idx, idx = T[idx]);
    for (i = 1; i <= max; ++i)
        printf("%d ", A[P[i]]);

    return 0;
}