Cod sursa(job #730580)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 6 aprilie 2012 16:03:06
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <fstream>
#include <algorithm>

#define f(x) ((x^(x - 1)) & x)

using namespace std;

const int MAX = 100050;
int n, v[MAX], nrm[MAX], res[MAX], up[MAX], aib[MAX], d[MAX], maxim, indice;

inline int query(int x)
{
    int mx = 0;
    for(;x; x -= f(x))
        if(d[aib[x]] > d[mx])
            mx = aib[x];
    return mx;
}

inline void update(int x, int poz)
{
    for(;x <= n; x += f(x))
        if(d[poz] > d[aib[x]])
            aib[x] = poz;
}

void afisare(int i)
{
    if(!i)
    {
        return;
    }
    afisare(up[i]);
    printf("%d ", res[i]);
}

int main()
{
    ifstream in("scmax.in");
    ofstream out("scmax.out");
    in>>n;
    for(int i = 1; i <= n; i++)
    {
        in>>v[i];
        nrm[i] = res[i] = v[i];
    }
    in.close();
    sort(nrm + 1, nrm + n + 1);
    int h = 1;
    for(int i = 2; i <= n; i++)
        if(nrm[i] != nrm[h])
            nrm[++h] = nrm[i];
    for(int i = 1; i <= n; i++)
        v[i] = lower_bound(nrm + 1, nrm + h + 1, v[i]) - nrm;
    for(int i = 1; i <= n; i++)
    {
        up[i] = query(v[i] - 1);
        d[i] = d[up[i]] + 1;
        update(v[i], i);
        if(d[i] > maxim)
        {
            maxim = d[i];
            indice = i;
        }
    }
    out<<maxim<<'\n';
    h = 0;
    for(; indice; indice = up[indice])
        nrm[++h] = res[indice];
    for(int i = h; i; --i)
        out<<nrm[i]<<" ";
    out.close();
    return 0;
}