Cod sursa(job #1093713)

Utilizator teoionescuIonescu Teodor teoionescu Data 28 ianuarie 2014 15:13:35
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include<fstream>
#include<algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
const int Nmax = 100005;
struct item{
    int val,pos;
} a[Nmax];
bool cmp1(item _a,item _b){
    return _a.val<_b.val;
}
bool cmp2(item _a,item _b){
    return _a.pos<_b.pos;
}
int v[Nmax];
struct aitem{
    int len,where;
} A[Nmax];
int Prev[Nmax],Seq[Nmax],K;
int N,M,Ans,Rec;
int lsb(int& x){
    return (x&(-x));
}
void Update(int j,int i,aitem val){
    while(i<=M){
        if(val.len>A[i].len){
            A[i].len=val.len;
            A[i].where=j;
        }
        i+=lsb(i);
    }
}
aitem Query(int i){
    aitem s;
    s.len=0,s.where=0;
    while(i){
        if(A[i].len>s.len){
            s=A[i];
        }
        i-=lsb(i);
    }
    return s;
}
int main(){
    in>>N;
    for(int i=1;i<=N;i++) in>>a[i].val,a[i].pos=i;
    sort(a+1,a+N+1,cmp1);
    for(int i=1;i<=N;i++){
        if(a[i].val!=a[i-1].val) M++;
        v[a[i].pos]=M;
    }
    for(int i=1;i<=N;i++){
        aitem down=Query(v[i]-1);
        down.len++;
        Prev[i]=down.where;
        down.where=i;
        Update(i,v[i],down);
        if(down.len>Ans){
            Ans=down.len;
            Rec=i;
        }
    }
    out<<Ans<<'\n';
    sort(a+1,a+N+1,cmp2);
    while(Rec){
        Seq[++K]=Rec;
        Rec=Prev[Rec];
    }
    for(int i=K;i>=1;i--) out<<a[Seq[i]].val<<' ';
    return 0;
}