Cod sursa(job #701621)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 1 martie 2012 16:52:00
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.34 kb
#include<stdio.h>
#include<assert.h>

#include<vector>

using namespace std;

const int knmax = 100005;
int no_num, sol, vals[knmax], pos_min[knmax], pred[knmax], d[knmax];
vector<int> sub_seq;

void read(){
    assert(freopen("scmax.in","r",stdin)!=NULL);
    scanf("%d",&no_num);
    for(int i = 1; i <= no_num; ++i)
        scanf("%d",&vals[i]);
}

int bs_lower(int val){
    int left = 1, right = sol, mid, last = 0;
    while(left <= right){
        mid = (left + right) / 2;
        if(vals[pos_min[mid]] < val){
            last = mid;
            left = mid + 1;
        }
        else
            right = mid - 1;
    }
    return last;
}

void solve(){
    int aux, i, j;
    for(i = 1; i <= no_num; ++i){
        aux = bs_lower(vals[i]);
        pred[i] = pos_min[aux];
        d[i] = aux + 1;
        if(aux == sol || vals[i] < vals[pos_min[aux + 1]]){
            pos_min[aux + 1] = i;
            sol = max(sol, aux + 1);
        }
    }
    for(i = 1; i <= no_num; ++i)
        if(d[i] == sol){
            for(j = i; j != 0;  j = pred[j])
                sub_seq.push_back(j);
            break;
        }
}

void write(){
    assert(freopen("scmax.out","w",stdout)!=NULL);
    printf("%d\n",sol);
    for(int i = sub_seq.size() - 1; i >= 0; --i)
        printf("%d ",vals[sub_seq[i]]);
}

int main(){
    read();
    solve();
    write();
    return 0;
}