Cod sursa(job #2134337)

Utilizator sulzandreiandrei sulzandrei Data 17 februarie 2018 20:55:58
Problema Subsir crescator maximal Scor 15
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;
std::ifstream in("scmax.in");
std::ofstream out("scmax.out");

const int MAX_N =100000 +10;
int N;
int v[MAX_N]{0}, pind[MAX_N]{0}, Tbest[MAX_N]{0};
struct node
{
    int val,p,aj;
    node(){val = 0; p = 0; aj =0;}
    //additional data
};
node best[MAX_N];
void Update(int n, int st, int dr, int a, int b,int val,int aj)
{
    if( a<=st && dr<= b)
    {
        best[n].val = val;
        best[n].p = a;
        best[n].aj = aj;
    }
    else
    {
        int mij = (st+dr)/2;

        if(a <= mij)
            Update(2*n,st,mij,a,b,val,aj);
        if(b > mij)
            Update(2*n+1,mij+1,dr,a,b,val,aj);

        if(best[2*n].val> best[2*n+1].val)
            best[n] = best[2*n];
        else
            best[n] = best[2*n+1];
    }
}
// fie a = 1, b = i-1, cautam in intervalul [a,b] max best[j],unde j=a,b si a[j] < a[i]

node Query(int n, int st, int dr, int a, int b, int ai)
{
    node nou,right;
    if( a<=st && dr<= b)
    {
        if (best[n].aj<ai)
            return best[n];
        return nou;
    }
    else
    {
        int mij = (st+dr)/2;
        if(a <= mij)
            nou = Query(2*n,st,mij,a,b,ai);
        if(b > mij)
            right = Query(2*n+1,mij+1,dr,a,b,ai);
        if(nou.val < right.val)
            nou = right;
        return nou;
    }
}
int main()
{
    in >> N;
    for(int i =1 ; i <= N ; i++)
    {
        in>>v[i];
        Update(1,1,N,i,i,1,v[i]);
        pind[i] =i;
        Tbest[i] = 1;
    }
    Tbest[0] = 0;
    int pozmaxbj;
    for(int i = 2 ; i <= N ; i++)
    {
        node nou  = Query(1,1,N,1,i-1,v[i]);
        pozmaxbj = nou.p;
        if(pozmaxbj!=0)
        {
            Tbest[i] = 1+Tbest[pozmaxbj];
            pind[i] = pozmaxbj;
            Update(1,1,N,i,i,Tbest[i],v[i]);
        }
    }
    int * el = max_element(Tbest+1,Tbest+1+N);
    int poz = 1;
    for(int i = 2 ; i <= N ; i++)
        if(Tbest[i]>Tbest[poz])
            poz = i;
    for(int i = *el ; i >=1 ; i--)
    {
        Tbest[i] = v[poz];
        poz = pind[poz];
    }
    out<<*el<<'\n';
    for(int i = 1 ; i<= *el ; i++)
        out<<Tbest[i]<<" ";

    return 0;
}