Cod sursa(job #1970619)

Utilizator ZeBuGgErCasapu Andreas ZeBuGgEr Data 19 aprilie 2017 14:50:18
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include<cstdio>
#include<algorithm>

using namespace std;

const int NMAX = 100000;

int n;
int val[1 + NMAX];
int ordered[1 + NMAX];
int from[1 + NMAX];

struct myaib
{
    int len;
    int pos;
    myaib(int a = 0, int b = 0){len = a; pos = b;}
} aib[1 + NMAX];

int comp(int a, int b)
{
    return a < b;
}

int norm_pos(int x)
{
    return (lower_bound(ordered + 1, ordered + 1 + n, x) - ordered);
}

myaib query(int i)
{
    myaib res;

    for(; i > 0; i -= (i & (-i)))
    {
        if(res.len < aib[i].len)
        {
            res = aib[i];
        }
    }

    return res;
}

void update(int new_len, int new_pos, int start)
{
    for(int i = start; i <= n; i += (i & (-i)))
    {
        if(new_len > aib[i].len)
        {
            aib[i].len = new_len;
            aib[i].pos = new_pos;
        }
    }
}

int main()
{
    freopen("scmax.in", "r", stdin);
    freopen("scmax.out", "w", stdout);

    scanf("%d", &n);

    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &val[i]);
        ordered[i] = val[i];
        from[i] = i;
    }

    sort(ordered + 1, ordered + 1 + n, comp);

    int pos;
    myaib temp;
    for(int i = 1; i <= n; i++)
    {
        pos = norm_pos(val[i]);
        temp = query(pos - 1);
        from[i] = temp.pos;
        update(temp.len + 1, i, pos);
    }

    /*for(int i = 1; i <= n; i++)
    {
        printf("%d: %d %d\n",i, aib[i].pos, aib[i].len);
    }*/

    temp = query(n);

    int curr = temp.pos;
    int ct = temp.len;
    int show[1 + NMAX];
    for(int i = 1; i <= ct; i++)
    {
        show[i] = val[curr];
        curr = from[curr];
    }

    printf("%d\n", ct);
    for(int i = ct; i > 0; i--)
    {
        printf("%d ", show[i]);
    }
}