Cod sursa(job #1225825)

Utilizator MaarcellKurt Godel Maarcell Data 3 septembrie 2014 18:27:08
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include <fstream>
#include <algorithm>
#include <iostream>
#define NMAX 100100
using namespace std;

int N,L,K, a[NMAX],b[NMAX],tree[5*NMAX],dp[NMAX],sol[NMAX],val,pos,qr,MAX;

void update(int nod, int l, int r){
    if (l==r){
        tree[nod]=max(tree[nod],val);
        return;
    }

    int mid=(l+r)/2;
    if (pos<=mid) update(nod*2,l,mid);
    else update(nod*2+1,mid+1,r);
    tree[nod]=max(tree[nod*2],tree[nod*2+1]);
}

void query(int nod, int l, int r){
    if (r<=qr){
        if (tree[nod]>MAX)
            MAX=tree[nod];
        return;
    }

    int mid=(l+r)/2;
    query(nod*2,l,mid);
    if (mid<qr) query(nod*2+1,mid+1,r);
}

int ind(int x){
    int l=1,r=L,mid=0;

    while (l<=r){
        mid=(l+r)/2;
        if (b[mid]>x)
            r=mid-1;
        else if (b[mid]<x)
            l=mid+1;
        else
            l=r+1;
    }

    return mid;
}

int main(){
    ifstream in("scmax.in");
    ofstream out("scmax.out");
    in >> N;

    int i;
    for (i=1; i<=N; i++){
        in >> a[i];
        b[i]=a[i];
    }
    sort(b+1,b+N+1);

    L=1; int last=b[L];
    for (i=2; i<=N; i++)
        if (b[i]!=last){
            b[++L]=b[i];
            last=b[L];
        }

    for (i=1; i<=N; i++){

        dp[i]=1,MAX=0;
        qr=ind(a[i])-1;
        if (qr)
            query(1,1,L);

        dp[i]+=MAX;
        val=dp[i],pos=qr+1;
        update(1,1,L);
    }

    MAX=0; int p=0;
    for (i=1; i<=N; i++)
        if (MAX<dp[i]){
            MAX=dp[i];
            p=i;
        }
    out << MAX << "\n";

    for (i=p; i>0; i--)
        if (dp[i]==MAX){
            sol[++K]=a[i];
            MAX--;
        }

    for (i=K; i>0; i--)
        out << sol[i] << " ";

    return 0;
}