Cod sursa(job #2282122)

Utilizator razviii237Uzum Razvan razviii237 Data 13 noiembrie 2018 11:28:06
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

ifstream f("scmax.in");
ofstream g("scmax.out");

const int maxn = 1e5+5, inf = 0x3f3f3f3f;

int aib[maxn], d[maxn], u[maxn], bk[maxn], n, i, v[maxn], lst[maxn], h, rez, irez, rz[maxn];

// tin indicii in aib
void update(int pos, int ind)
{
    int x = pos;
    do
    {
        if(d[ind] > d[aib[x]]) {
            aib[x] = ind;
        }
        x += (x & (-x));
    }while(x <= n);
}

int query(int y)
{
    int x = y, mx = -inf, imx = 0;
    for(; x >= 1; x -= (x & (-x))) {
        if(d[aib[x]] >= mx) {
            mx = d[aib[x]];
            imx = aib[x];
        }
    }
    return imx;
}

int main()
{
    f >> n;

    for(i = 1; i <= n; i ++) {
        f >> v[i];
        bk[i] = lst[i] = v[i];
    }

    sort(lst + 1, lst + n + 1);

    // scot dublurile
    h = 1;
    for(i = 2; i <= n; i ++) {
        if(lst[i] != lst[h]) {
            lst[++h] = lst[i];
        }
    }

    // nr mici
    for(i = 1; i <= n; i ++) {
        v[i] = lower_bound(lst + 1, lst + n + 1, v[i]) - lst;
    }

    // solve
    for(i = 1; i <= n; i ++) {
        u[i] = query(v[i]-1);
        d[i] = d[u[i]]+1;
        update(v[i], i);

        if(d[i] > rez) {
            rez = d[i];
            irez = i;
        }
    }

    // afisare
    int rr = rez;
    while(rr > 0)
    {
        rz[rr--] = bk[irez];
        irez = u[irez];
    }

    g << rez << '\n';
    for(i = 1; i <= rez; i ++) {
        g << rz[i] << ' ';
    }

    f.close();
    g.close();
    return 0;
}