Cod sursa(job #2483517)

Utilizator 0738076326Simon Wil 0738076326 Data 29 octombrie 2019 20:54:10
Problema Subsir crescator maximal Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.02 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 1e5 + 5;
int arb[4 * NMAX],n,value,a[NMAX];
pair <int, int> v[NMAX];

bool cmp(pair <int, int> X, pair <int, int> Y){
    return X.first < Y.first;
}

void update(int node, int lo, int hi, int x, int y){
    if(lo == hi){
        arb[node] = y;
        return;
    }
    int mid = (lo + hi) / 2;
    if(x <= mid)
        update(2 * node, lo, mid, x, y);
    else
        update(2 * node + 1, mid + 1, hi, x, y);
    arb[node] = max(arb[2 * node], arb[2 * node + 1]);
}

int query(int node, int lo, int hi, int x, int y){
    if(lo > hi) return 0;
    if(lo >= x && hi <= y){
        return arb[node];
    }
    int mid = (lo + hi) / 2, value = 0;
    if(x <= mid)
        value = query(2 * node, lo, mid, x, y);
    if(y > mid)
        value = max(value, query(2 * node + 1, mid + 1, hi, x, y));
    return value;
}

int query_pos(int node, int lo, int hi, int x, int y, int value){
    if(lo == hi)
        return lo;
    int mid = (lo + hi) / 2;

    if(y > mid && arb[2 * node + 1] == value)
        return query_pos(2 * node + 1, mid + 1, hi, x, y, value);
    if(x <= mid)
        return query_pos(2 * node, lo, mid, x, y, value);
    return -1;
}

void see(int x, int lim){
    if(x == 0) return;
    int value = query_pos(1,1,n,1, lim,x);
    see(x - 1, value - 1);
    g << a[value] << " " ;
}

int main(){
    int i;
    f >> n;
    for(i = 1 ; i <= n ; i++){
        f >> v[i].first;
        a[i] = v[i].first;
        v[i].second = i;
    }

    sort(v + 1, v + n + 1, cmp);

    for(i = 1 ; i <= n ; i++){
        value = query(1,1,n,1,v[i].second) + 1;
        update(1,1,n,v[i].second, value);
        if(v[i].first == v[i + 1].first){
            for(i = i + 1 ; i <= n && v[i].first == v[i - 1].first ; i++)
                update(1,1,n,v[i].second, value);
            i--;
        }
    }

    g << arb[1] << "\n";
    see(arb[1], n);

    return 0;
}