Cod sursa(job #779242)

Utilizator stefanzzzStefan Popa stefanzzz Data 17 august 2012 09:35:05
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include <fstream>
#include <algorithm>
using namespace std;

struct nr{
    long index,val;};

long n,i,cnt,x,pd[100005],ai[400010],back[100005],back_ai[400010],norm[100005],mx,bk,ind;
nr v[100005];

bool comp1(nr a,nr b){
    return a.val<b.val;}
bool comp2(nr a,nr b){
    return a.index<b.index;}

void maxim_ai(long nod,long st,long dr);
void actualizare(long nod,long st,long dr);
void afisare(long a);

int main()
{
    freopen("scmax.in","r",stdin);
    freopen("scmax.out","w",stdout);
    scanf("%ld",&n);
    for(i=1;i<=n;i++){
        scanf("%ld",&v[i].val);
        v[i].index=i;}
    sort(v+1,v+n+1,comp1);
    x=v[1].val;
    v[1].val=(++cnt);
    norm[cnt]=x;
    for(i=2;i<=n;i++){
        if(v[i].val==x)
            v[i].val=cnt;
        else{
            x=v[i].val;
            v[i].val=(++cnt);
            norm[cnt]=x;}}
    sort(v+1,v+n+1,comp2);
    for(i=1;i<=n;i++){
        x=v[i].val;
        mx=bk=0;
        maxim_ai(1,1,cnt);
        pd[i]=mx+1;
        back[i]=bk;
        actualizare(1,1,cnt);}
    mx=0;
    for(i=1;i<=n;i++)
        if(pd[i]>mx){
            mx=pd[i];
            ind=i;}
    printf("%ld\n",mx);
    afisare(ind);
    return 0;
}

void maxim_ai(long nod,long st,long dr){
    if(ai[nod]<=mx)
        return;
    if(dr<x){
        if(ai[nod]>mx){
            bk=back_ai[nod];
            mx=ai[nod];}}
    else{
        long mij=(st+dr)/2;
        maxim_ai(2*nod,st,mij);
        if(mij+1<x)
            maxim_ai(2*nod+1,mij+1,dr);}}

void actualizare(long nod,long st,long dr){
    if(st==dr){
        if(ai[nod]<mx+1){
            back_ai[nod]=i;
            ai[nod]=mx+1;}}
    else{
        long mij=(st+dr)/2;
        if(x<=mij){
            actualizare(2*nod,st,mij);
            if(ai[2*nod]>ai[nod]){
                ai[nod]=ai[2*nod];
                back_ai[nod]=back_ai[2*nod];}}
        else{
            actualizare(2*nod+1,mij+1,dr);
            if(ai[2*nod+1]>ai[nod]){
                ai[nod]=ai[2*nod+1];
                back_ai[nod]=back_ai[2*nod+1];}}}}

void afisare(long a){
    if(back[a])
        afisare(back[a]);
    printf("%ld ",norm[v[a].val]);}