Cod sursa(job #1518085)

Utilizator theprdvtheprdv theprdv Data 5 noiembrie 2015 14:28:41
Problema Subsir crescator maximal Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.2 kb
/* Binary indexed tree solution */

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

#define MAXN 100005
#define DIM (1 << 13)
#define lastSB(x) (x & -x)

int N, A[MAXN], P[MAXN], T[MAXN], BIT[MAXN], IDX[MAXN], max, idx;
int pos = DIM;
char buf[DIM];

void read(int* val)
{
    *val = 0;

    while (buf[pos] < '0' || buf[pos] > '9')
        if (++pos >= DIM) fread(buf, 1, DIM, stdin), pos = 0;

    while(buf[pos] >= '0' && buf[pos] <= '9')
    {
        *val = *val * 10 + buf[pos] - '0';
        if (++pos == DIM) fread(buf, 1, DIM, stdin), pos = 0;
    }
}

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 = BIT[idx], i = IDX[idx];

    return i;
}

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

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

    assert(freopen("secvmax.in", "r", stdin));
    freopen("secvmax.out", "w", stdout);

    int i;
    read(&N);

    for (i = 1; i <= N; ++i)
        read(&A[i]),
        P[i] = i;

    Qsort(1, N);

    for (i = 1; i <= N; ++i)
    {
        if (A[P[i]] == A[P[i - 1]]) continue;
        int before = query(P[i]);
        T[P[i]] = before;
        update(P[i], BIT[before] + 1);

        if (BIT[before] + 1 > max)
            max = BIT[before] + 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]]);

    //fprintf(stderr, "%.3lf\n\n", (float)clock() / CLOCKS_PER_SEC);

    return 0;
}