Cod sursa(job #1937182)

Utilizator dr55Dan Rusu dr55 Data 23 martie 2017 19:29:57
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <fstream>
#include <algorithm>

const int kNMAX = 100005;

int N, result[kNMAX], v[kNMAX], lst[kNMAX], D[kNMAX], tree[kNMAX], up[kNMAX], bst;

void read()
{
    std::ifstream fin("scmax.in");
    fin >> N;
    for (int i = 1; i <= N; i++)
    {
        fin >> v[i];
        result[i] = lst[i] = v[i];
    }
    fin.close();
}

void print()
{
    std::ofstream fout("scmax.out");
    fout << D[bst] << '\n';
    int i, h;
    for (h = 0, i = bst; i; i = up[i])
    {
        h++;
        lst[h] = result[i];
    }
    for (i = h; i; --i)
    {
        fout << lst[i] << ' ';
    }
    fout << '\n';
    fout.close();
}

void update(int value, int index)
{
    for (; value <= N; value += value^(value-1) & value)
    {
        if (D[index] > D[tree[value]])
        {
            tree[value] = index;
        }
    }
}

int query(int value)
{
    int mx = 0;
    for ( ; value; value -= value^(value-1) & value)
    {
        if (D[tree[value]] > D[mx])
        {
            mx = tree[value];
        }
    }
    return mx;
}

void solve()
{
    int i, h = 1;
    std::sort(lst + 1, lst + N + 1);
    for (i = 2; i <= N; i++)
    {
        if (lst[i] != lst[h])
        {
            lst[++h] = lst[i];
        }
    }

    for ( i = 1; i <= N; i++)
    {
        v[i] = std::lower_bound(lst + 1, lst + h + 1, v[i]) - lst;
    }

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

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

int main()
{
    read();
    solve();
    print();
    return 0;
}