Cod sursa(job #1923308)

Utilizator TibixbAndrei Tiberiu Tibixb Data 10 martie 2017 22:14:05
Problema Subsir crescator maximal Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include<fstream>
#include<vector>
#include<algorithm>
#define NMAX 100005
using namespace std;
pair<int, int> A[4 * NMAX];
pair<int, int> a[NMAX];
int t[NMAX], d[NMAX], b[NMAX];
int n, val, poz;
pair<int, int> q;
int nod;
int sol, _begin;
int na;
ifstream cin("scmax.in");
ofstream cout("scmax.out");
/*pair<int, int> max_pair(pair<int, int> x, pair<int, int> y)
{
    if(x.first == y.first)
    {
        return x.second < y.second;
    }
    return x.first < y.first;
}*/
void _query(int st, int dr, int nod, int a, int b)
{
    if(a <= st && dr <= b)
    {
        q = max(A[nod], q);
        return;
    }
    int mij = st + (dr - st) / 2;
    if(a <= mij)
    {
        _query(st, mij, 2 * nod, a, b);
    }
    if(b > mij)
    {
        _query(mij + 1, dr, 2 * nod + 1, a, b);
    }
}
void _update(int st, int dr, int nod, int poz, int val)
{
    if(st == dr)
    {
        A[nod].first = val;
        A[nod].second = st;
        return;
    }
    int mij = st + (dr - st) / 2;
    if(poz <= mij)
    {
        _update(st, mij, 2 * nod, poz, val);
    }
    else
    {
        _update(mij + 1, dr, 2 * nod + 1, poz, val);
    }

    A[nod] = max(A[2 * nod], A[2 * nod + 1]);
}
void drum(int nod)
{
    if(t[nod] == 0)
    {
        cout << b[nod] << " ";
        return;
    }
    drum(t[nod]);
    cout << b[nod] << " ";
}
void normalizare()
{
    na = 1;
    for(int i = 1 + 1; i <= n; i++)
    {
        if(a[i].first != a[na].first)
        {
            a[++na] = a[i];
        }
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i].first;
        a[i].second = i;
    }

    for(int i = 1; i <= n; i++)
    {
        b[i] = a[i].first;
    }

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

    normalizare();

    for(int i = 1; i <= n; i++)
    {
        q = make_pair(0, 0);

        val = a[i].first;
        poz = a[i].second;

        _query(1, na, 1, 1, poz);

        d[poz] = q.first + 1;
        if(d[poz] > sol)
        {
            sol = d[poz];
            _begin = poz;
        }

        t[poz] = q.second;

        _update(1, na, 1, poz, q.first + 1);
    }
    cout << sol << "\n";
    drum(_begin);
    return 0;
}