Cod sursa(job #1842922)

Utilizator mihai.alphamihai craciun mihai.alpha Data 7 ianuarie 2017 19:33:28
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <stdio.h>
#include <algorithm>

#define zeros(x) ((x ^ (x - 1)) & x)
#define r fscanf
#define pr fprintf
#define MAX 100000

int v[MAX + 1], Aib[MAX + 1], last[MAX + 1], res[MAX + 1], dp[MAX + 1], up[MAX + 1], bst;

FILE *f, *g;

int N;

inline void update(int x, int val)  {
    for(int i = x;i <= N;i += zeros(i))
        if(dp[val] > dp[Aib[i]])
            Aib[i] = val;
}

inline int query(int x)  {
    int ret = 0;
    for(int i = x;i > 0;i -= zeros(i))
        if(dp[Aib[i]] > dp[ret])
        ret = Aib[i];
    return ret;
}

bool cmp(int a, int b)  {
    return a < b;
}

inline int caut(int x, int k)  {
    int ret = 0, pas = 1 << 17;

    while(pas)  {
        if(ret + pas <= k && last[ret + pas] <= x)
            ret += pas;
        pas >>= 1;
    }

    return ret;
}

int main()  {
    f = fopen("scmax.in", "r");
    g = fopen("scmax.out", "w");

    r(f, "%d", &N);

    for(int i = 1;i <= N;i++)
        r(f, "%d", &v[i]), last[i] = v[i], res[i] = v[i];

    std::sort(last + 1, last + N + 1, cmp);

    int k = 1;

    for(int i = 2;i <= N;i++)
        if(last[i] != last[k])
            last[++k] = last[i];

    for(int i = 1;i <= N;i++)  {
        v[i] = caut(v[i], k);
    }

    for(int i = 1;i <= N;i++)  {
        up[i] = query(v[i] - 1);
        dp[i] = dp[up[i]] + 1;
        update(v[i], i);
    }

    for(int i = 1;i <= N;i++)  {
        if(dp[bst] < dp[i])
            bst = i;
    }

    pr(g, "%d\n", dp[bst]);

    int h = 0, i;
    for(h = 0, i = bst;i;i = up[i])
        last[++h] = res[i];

    for(int i = h;i;i--)
        pr(g, "%d ", last[i]);

    fclose(f);
    fclose(g);

    return 0;
}