Cod sursa(job #1611495)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 24 februarie 2016 10:33:02
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <fstream>
using namespace std;

struct p_v_p{
    int poz, val;
    p_v_p(): poz(0), val(0){}
    p_v_p(const int p, const int v): poz(p), val(v){}
};

bool operator<(const p_v_p& a, const p_v_p& b){
    return a.val < b.val || (a.val == b.val && a.poz > b.poz);
}

class arbint_poz{
    int n = 0;
    vector<p_v_p> buf;
public:
    arbint_poz(const int N): n(N), buf(2*n, p_v_p(0, 0)){
        for(int i = 0; i < n; ++i){
            buf[i+n].poz = i;
        }
        for(int i = n-1; i > 0; --i){
            buf[i] = max(buf[2*i], buf[2*i+1]);
        }
    }
    void update(int p, const int v){
        buf[p+=n].val = v;
        for(p /= 2; p > 0; p /= 2){
            buf[p] = max(buf[2*p], buf[2*p+1]);
        }
    }
    p_v_p query(int st, int dr){
        st += n, dr += n+1;
        p_v_p rez = buf[st];
        for( ; st < dr; st /= 2, dr /= 2){
            if(st%2 == 1){
                rez = max(rez, buf[st++]);
            }
            if(dr%2 == 1){
                rez = max(rez, buf[--dr]);
            }
        }
        return rez;
    }
};

int main()
{
    ifstream f("scmax.in");
    ofstream g("scmax.out");
    int n;
    f >> n;
    vector<p_v_p> v(n);
    vector<int> valori(n);
    for(int i = 0; i < n; ++i){
        f >> v[i].val;
        valori[i] = v[i].val;
        v[i].poz = i;
    }
    sort(v.begin(), v.end());

    vector<int> prev(n, -1), len(n, 0);
    arbint_poz ai(n);

    for(int i = 0; i < n; ++i){
        if(v[i].poz == 0){
            prev[0] = 0, len[0] = 1;
            ai.update(0, 1);
            continue;
        }


        const p_v_p cur = ai.query(0, v[i].poz-1);
        len[v[i].poz] = cur.val+1;
        prev[v[i].poz] = cur.poz;
        ai.update(v[i].poz, cur.val+1);
    }

    vector<int> rez;
    for(int i = ai.query(0, n-1).poz; ; ){
        rez.push_back(valori[i]);
        if(len[i] == 1){
            break; }
        i = prev[i];
    }
    reverse(rez.begin(), rez.end());
    g << rez.size() << '\n';
    for(int i = 0; i < rez.size(); ++i){
        g << rez[i] << ' ';
    }
    return 0;
}