Cod sursa(job #931871)

Utilizator vendettaSalajan Razvan vendetta Data 28 martie 2013 15:40:36
Problema Subsir crescator maximal Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

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

#define nmax 100005
#define ll long long

int n, v[nmax], poz[nmax], inAint[nmax], aint[nmax*4], dp[nmax];
pair<int,int> a[nmax];
int t[nmax];

void citeste(){
    f >> n;
    int x = 0;
    for(int i=1; i<=n; ++i){
        f >> x; a[i] = make_pair( x, i);
        v[i] = x;
    }
}

void debug(){
    for(int i=1; i<=n; ++i) cout << inAint[i] << " ";
    cout << "\n";
    for(int i=1; i<=n; ++i) cout << poz[i] << " ";
    cout << "\n";
    cout << "\n";
}

void query(int nod, int st, int dr, int a, int b, int &Max, int &Poz){
    if (a <= st && dr <= b){
        if (Max < dp[ aint[nod] ]){
            Max = dp[ aint[nod] ]; Poz = aint[nod];
        }
        return;
    }else {
        int mij = (st + dr) >> 1;
        if (a <= mij) query(nod*2, st, mij, a, b, Max, Poz);
        if (b > mij) query(nod*2+1, mij+1, dr, a, b, Max, Poz);
    }
}

void update(int nod, int st, int dr, int poz, int val){
    if (st == dr){
        aint[nod] = val;
        return;
    }else {
        int mij = (st + dr) >> 1;
        if (poz <= mij) update(nod*2, st, mij, poz, val);
                   else update(nod*2+1, mij+1, dr, poz, val);
        aint[nod] = aint[nod*2];
        if ( dp[ aint[nod] ] < dp[ aint[nod*2+1] ] ){
            aint[nod] = aint[nod*2+1];
        }
    }
}

void bagaDrum(int x){
    if (t[x] != 0) bagaDrum(t[x]);
    g << v[x] << " ";
}

void bagaPoz(){
    for(int i=1; i<=n; ++i){
        inAint[ a[i].second ] = i;
    }
    int x=1;
    for(int i=2; i<=n; ++i){
        if (a[i].first != a[i-1].first){
            poz[ a[i-1].second ] = x;
            ++x;
        }else poz[ a[i-1].second ] = x;
    }
    poz[a[n].second] = x;
    //debug();

    for(int i=1; i<=n; ++i){
        int Max = 0; int Poz = 0;
        if (poz[i] > 1 ) query(1, 1, n, 1, poz[i]-1, Max, Poz);
        dp[i] = Max + 1;
        t[i] = Poz;
        update(1, 1, n, inAint[i], i);
    }
    int Poz = 0; int Max = 0; for(int i=1; i<=n; ++i){
        if (Max < dp[i]){
            Max = dp[i]; Poz = i;
        }
    }
    g << Max << "\n";
    bagaDrum(Poz);
}

void rezolva(){
    sort(a+1, a+n+1);
    bagaPoz();
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}