Cod sursa(job #1322946)

Utilizator radu_cebotariRadu Cebotari radu_cebotari Data 20 ianuarie 2015 15:44:48
Problema Subsir crescator maximal Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include<fstream>
#include<algorithm>
#include<iostream>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
const int NMAX = 100000;

struct numar{
    int vl;
    int pz;
    int k;
};
numar v[NMAX + 5],sortat[NMAX + 5];

int n,maxim,dp[NMAX + 5],pozitie,pr[NMAX + 5],prim,el[NMAX + 5];

struct arbore{

    int lgmax;
    int valoare;
};
arbore arb[3*NMAX + 5];

void read()
{

    in>>n;
    for(int i = 1 ; i <= n ; i++)
    {

        in>>sortat[i].vl;
        sortat[i].pz = i;
    }
}

bool cmp(numar a,numar b)
{

    return a.vl < b.vl;

}

void normalizare()
{

    sort(sortat+1,sortat+n+1,cmp);
    int h = 0;
    for(int i = 1 ; i <= n ; i++)
    {
        if(sortat[i].vl != sortat[i-1].vl){
            ++h;
            el[h] = sortat[i].vl;
        }
        v[sortat[i].pz].k = h;
        v[sortat[i].pz].vl = sortat[i].vl;
    }
}

void update(int nod,int left,int right,int poz,int val)
{

    if(left == right){
        arb[nod].valoare = poz;
        arb[nod].lgmax = val;
        return;
    }
    int mid = (left + right)/2;
    if(poz <= mid)
        update(2*nod,left,mid,poz,val);
    else
        update(2*nod+1,mid + 1,right,poz,val);

    if(arb[2*nod+1].lgmax > arb[2*nod].lgmax){
        arb[nod].lgmax = arb[2*nod + 1].lgmax;
        arb[nod].valoare = arb[2*nod + 1].valoare;
    }
    else{
        arb[nod].lgmax = arb[2*nod].lgmax;
        arb[nod].valoare = arb[2*nod].valoare;
    }
}

void query(int nod,int left,int right,int st,int fn)
{

    if(st <= left && right <= fn){
        if(maxim < arb[nod].lgmax){
            maxim = arb[nod].lgmax;
            pozitie = arb[nod].valoare;
        }
        return;
    }
    int mid = (left + right)>>1;
    if(st <= mid)
        query(2*nod,left,mid,st,fn);
    if(fn > mid)
        query(2*nod+1,mid + 1,right,st,fn);
}

int main()
{

    int solmax = 1;
    pr[n] = -1;
    read();
    normalizare();
    prim = v[n].k;
    dp[n] = 1;
    update(1,1,n,v[n].k,1);
    for(int i = n-1 ; i >= 1 ; i--){
        maxim = 0;
        pozitie = -1;
        query(1,1,n,v[i].k+1,n+1);
        dp[i] = maxim + 1;
        pr[v[i].k] = pozitie;
        update(1,1,n,v[i].k,dp[i]);
        if(solmax < maxim + 1){
            solmax = maxim + 1;
            prim = v[i].k;
        }
    }
    out<<solmax<<"\n";
    while(prim != -1){
        out<<el[prim]<<" ";
        prim = pr[prim];
    }
    return 0;
}