Cod sursa(job #1842940)

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

#define zeros(x) ((x ^ (x - 1)) & x)
#define MAX 100000

#define BUF 1 << 17

FILE *f, *g;

char buf[BUF];
int pos = BUF;

inline char nxt()  {
    if(pos == BUF) fread(buf, 1, BUF, f), pos = 0;

    return buf[pos++];
}

inline int r()  {
    int x = 0;
    char ch;
    ch = nxt();

    while(!isdigit(ch))
        ch = nxt();

    while(isdigit(ch))  {
        x = x * 10 + ch - '0';
        ch = nxt();
    }

    return x;
}

int out_loc = 0;
char obuf[BUF];


inline void write_ch(char ch)  {
    if (out_loc == BUF) {
        fwrite(obuf, 1, BUF, g);
        out_loc = 0;
        obuf[out_loc++] = ch;
    } else {
        obuf[out_loc++] = ch;
    }
}


inline void pr(int nr)  {
    if (nr <= 9) {
        write_ch(nr + '0');
    } else {
        pr(nr / 10);
        write_ch(nr % 10 + '0');
    }
}

inline void write_appendix()  {
    fwrite(obuf, 1, out_loc, g);
}

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

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");
    N = r();

    for(int i = 1;i <= N;i++)
        v[i] = r(), 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(dp[bst]);
    write_ch('\n');

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

    for(int i = h;i;i--)
        pr(last[i]), write_ch(' ');

    write_appendix();

    fclose(f);
    fclose(g);

    return 0;
}