Cod sursa(job #3208349)

Utilizator alexandru_ioan.06Alexandru Ioan alexandru_ioan.06 Data 28 februarie 2024 12:38:32
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda 28_februarie_simulare_oji_2024_clasele_11_12 Marime 3.14 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("scmax.in");
ofstream fout ("scmax.out");

const int maxDim = 1e5 + 1 , INF = 1e9;

int N , K , a[maxDim] , b[maxDim] , dp[maxDim] , prevv[maxDim];
unordered_map <int , int> poz , poz1;

struct Elem
{
    int v;
    int p;
}seg_tree[4 * maxDim];

class ST
{
private:

    void Update_Node (int node)
    {
        if(seg_tree[2 * node].v > seg_tree[2 * node + 1].v)
        {
            seg_tree[node].v = seg_tree[2 * node].v;
            seg_tree[node].p = seg_tree[2 * node].p;
        }
        else
        {
            seg_tree[node].v = seg_tree[2 * node + 1].v;
            seg_tree[node].p = seg_tree[2 * node + 1].p;
        }
    }
    void Update (int node , int l , int r , int p , int R)
    {
        if(l == r)
        {
            if(seg_tree[node].v < R)
                seg_tree[node].v = R , seg_tree[node].p = p;
        }
        else
        {
            int m = (l + r) / 2;
            if(p <= m)
                Update(2 * node , l , m , p , R);
            else
                Update(2 * node + 1 , m + 1 , r , p , R);
            Update_Node(node);
        }
    }
    pair<int , int> Query (int node , int l , int r , int l1 , int r1)
    {
        if(l >= l1 && r <= r1)
            return make_pair(seg_tree[node].v , seg_tree[node].p);
        else
        {
            int m = (l + r) / 2;
            if(r1 <= m)
                return Query(2 * node , l , m , l1 , r1);
            else if(l1 > m)
                return Query(2 * node + 1 , m + 1 , r , l1 , r1);
            else
            {
                pair<int , int> A , B;
                A = Query(2 * node , l , m , l1 , r1);
                B = Query(2 * node + 1 , m + 1 , r , l1 , r1);
                if(A.first > B.first)
                    return A;
                return B;
            }
        }
    }
public:
    void Update (int p , int val)
    {
        Update(1 , 1 , N , p , val);
    }
    pair<int,int> Query1(int p)
    {
        return Query(1 , 1 , N , 1 , p);
    }
};

int main()
{
    fin >> N;
    for (int i = 1; i <= N; ++i)
    {
         fin >> a[i];
         b[i] = a[i];
    }
    sort (b + 1 , b + N + 1);
    for (int i = 1; i <= N; ++i)
        if(!poz[b[i]])
            poz[b[i]] = ++K;
    ST SGT;
    dp[1] = 1;
    SGT.Update(poz[a[1]] , 1);
    int P = 1;
    for (int i = 2; i <= N; ++i)
    {
        pair <int , int> T;
        if(poz[a[i]] != 1)
        {
             T = SGT.Query1(poz[a[i]] - 1);
             dp[i] = 1 + T.first;
             SGT.Update(poz[a[i]] , dp[i]);
        }
        else
        {
            dp[i] = 1;
            SGT.Update(poz[a[i]] , 1);
        }
        if(dp[i] > dp[P])
            P = i;
    }
    fout << dp[P] << "\n";
    stack<int>st;
    st.push(a[P]);
    int P1 = P;
    for (int i = P - 1; i >= 1; --i)
    {
        if(a[i] < a[P1] && dp[i] + 1 == dp[P1])
        {
            P1 = i;
            st.push(a[P1]);
        }
    }
    while(!st.empty())
    {
        fout << st.top() << " ";
        st.pop();
    }
}