Cod sursa(job #2353236)

Utilizator rexlcdTenea Mihai rexlcd Data 24 februarie 2019 00:29:41
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;

typedef pair < int , int > pii;

struct elem
{
    int first, second, third;
};

const int NMAX = 100002;

elem v[NMAX];
pii best[4 * NMAX];
int ansb[NMAX], up[NMAX];
int n, m;

bool cmp1(elem a, elem b)
{
    return a.first < b.first;
}

bool cmp2(elem a, elem b)
{
    return a.second < b.second;
}

void update(int node, int st, int dr, int a, int b, int val, int pos)
{
    if(a <= st && dr <= b)
    {
        best[node] = {val, pos};
    }
    else
    {
        int m = (st + dr) / 2;
        if(a <= m)
            update(node * 2, st, m, a, b, val, pos);
        if(b > m)
            update(node * 2 + 1, m + 1, dr, a, b, val, pos);

        if(best[node * 2].first > best[node * 2 + 1].first)
            best[node] = best[node * 2];
        else
            best[node] = best[node * 2 + 1];
    }
}

pii query(int node, int st, int dr, int a, int b)
{
    if(a <= st && dr <= b)
    {
        return best[node];
    }
    else
    {
        int m = (st + dr) / 2;
        pii rezst = {0, 0}, rezdr = {0, 0};
        if(a <= m)
            rezst = query(node * 2, st, m, a, b);
        if(b > m)
            rezdr = query(node * 2 + 1, m + 1, dr, a, b);

        if(rezst.first > rezdr.first)
            return rezst;
        else
            return rezdr;
    }
}

int main()
{
    ifstream f("scmax.in");
    ofstream g("scmax.out");
    f >> n;
    for(int i = 1; i <= n; i++)
    {
        f >> v[i].first;
        v[i].second = i;
    }

    sort(v + 1, v + n + 1, cmp1);
    for(int i = 1, ind = 1; i <= n; i++)
    {
        int val = v[i].first;
        while(i <= n && v[i].first == val)
            v[i++].third = ind;
        ind++;
        i--;
        m++;
    }
    sort(v + 1, v + n + 1, cmp2);

    int ansa = 1, pos = 1;
    update(1, 1, m, v[1].third, v[1].third, 1, 1);
    for(int i = 2; i <= n; i++)
    {
        pii r = {1, i};
        if(1 <= v[i].third - 1)
        {
            r = query(1, 1, m, 1, v[i].third - 1);
            if(r.first + 1 > ansa)
            {
                ansa = r.first + 1;
                pos = i;
            }
            update(1, 1, m, v[i].third, v[i].third, r.first + 1, i);
        }
        else
        {
            update(1, 1, m, v[i].third, v[i].third, r.first, i);
        }
        up[i] = r.second;
    }

    g << ansa << '\n';
    int h = 0;
    for(int i = pos; i; i = up[i])
    {
        ansb[++h] = v[i].first;
        if(up[i] == i)
            break;
    }
    for(int i = h; i; i--)
        g << ansb[i] << " ";
    g << '\n';
    f.close();
    g.close();
    return 0;
}