Cod sursa(job #1894233)

Utilizator MarCelDragMacel Dragan MarCelDrag Data 26 februarie 2017 17:25:45
Problema Subsir crescator maximal Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 3.41 kb
#include <fstream>
#include <algorithm>
using namespace std;
#define valMax 100005
struct nod{
    int ls,ld,ea;
    nod *st,*dr;
};
int n,si[valMax], // sirul initial nemodif
    s[valMax], // sirul normat
    id[valMax], // index pentru normare
    l[valMax], // lungimea maxima subsir cu elemente pana la poz curenta
    ea[valMax], // index element anterior elementului curent in subsir
    ss[valMax]; // subsirul de lunfime maxima
ifstream in("scmax.in");
ofstream out("scmax.out");
nod *arbore(int st,int dr){
    nod *nc;
    nc=new nod;
    nc->ls=st;
    nc->ld=dr;
    nc->ea=0;
    if(st==dr){
        nc->st=NULL;
        nc->dr=NULL;
    }
    else{
        int m=(st+dr)/2;
        nc->st=arbore(st,m);
        nc->dr=arbore(m+1,dr);
    }
    return nc;
}
int cautare(nod *nc,int val){
    int jMax=0;
    if(nc!=NULL){
        if(nc->ls<=val && val<=nc->ld){
            if(l[jMax]<l[nc->ea])
                jMax=nc->ea;
            int m=(nc->ls+nc->ld)/2;
            if(val<=m){
                int j=cautare(nc->st,val);
                if(l[jMax]<l[j])
                    jMax=j;
            }
            else{
                int j=cautare(nc->dr,val);
                if(l[jMax]<l[j])
                    jMax=j;
            }
        }
        else{
            if(nc->ld<=val)
                if(l[jMax]<l[nc->ea])
                    jMax=nc->ea;
        }
    }
    return jMax;
}
void actualizare(nod *nc,int ls,int iVal){
    if(nc!=NULL){
        if(ls<=nc->ls){ // intervalul nodului inclus in intervalul de actualizat
            if(l[nc->ea]<l[iVal]) // actualizare nod curent
                nc->ea=iVal;
        }
        else{
            if(nc->ls<ls && ls<nc->ld){ // intervalul nodului are zona de inceput in afara intervalului de actualizat
                int m=(nc->ls+nc->ld)/2;
                if(ls<=m){
                    actualizare(nc->st,ls,iVal);
                    actualizare(nc->dr,ls,iVal);
                }
                else{
                    actualizare(nc->dr,ls,iVal);
                }
            }
            else{
                actualizare(nc->dr,ls,iVal);
            }
        }
    }
}
int main()
{
    // citire
    in>>n;
    int vMax=0;
    for (int i = 1; i <= n; i++){
        in>>s[i];
        si[i]=id[i]=s[i];
    }
    //normare sir
    sort(id+1,id+n);
    int j=1;
    for (int i = 1; i <= n; i++){
        if(id[i]!=id[j]){
            id[j]=id[i];
            j++;
        }
    }
    for (int i=1;i<=n; i++)
        s[i] = lower_bound(id+1, id+j, s[i])-id;
    vMax=j;
    nod *r=NULL;
    r=arbore(1,vMax);
    // cautare subsir de lungime maxima
    for (int i = 1; i <= n; i++){
        int jMax=cautare(r,s[i]);
        l[i]=l[jMax]+1;
        ea[i]=jMax;
        actualizare(r,s[i]+1,i);
    }
    // alegere subsir de lungime maxima din cele maxime ale fiecarui nivel
    // deoarece in D[] avem subsirul de lungime maxima care se termina cu poz curenta
    // si pot exista cazuri in care pe ultima pozitie sa avem un subsir mai scurt
    // ex: 1 3 5 8 2
    int iMax=0;
    for (int i = 1; i <= n; i++)
        if (l[iMax] < l[i])
            iMax = i;
    //afisare
    out<<l[iMax]<<'\n';
    for (int j=l[iMax],i = iMax; i>0;i=ea[i])
         ss[j--]=si[i];

    for (int i = 1; i<=l[iMax]; i++)
        out<<ss[i]<<' ';
    out<<'\n';
    return 0;
}