Cod sursa(job #1238748)

Utilizator radu_cebotariRadu Cebotari radu_cebotari Data 7 octombrie 2014 17:32:12
Problema Subsir crescator maximal Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
#include<fstream>
#include<iostream>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");

struct arb{
    int m;
    int sol;
    int p;
};
arb arbore[1000009],maxim;
int pz[100009],lg[100009],v[100009],sol1,sol2,sol3,n;

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

    if(left == right){
        arbore[nod].m = val;
        arbore[nod].p = poz;
        arbore[nod].sol = val2;
        return;
    }
    int mij = (left+right)/2;
    if(poz <= mij) update(poz,val,val2,nod*2,left,mij);
    if(poz > mij) update(poz,val,val2,nod*2+1,mij+1,right);
    if(arbore[nod*2+1].sol > arbore[nod*2].sol){
        arbore[nod].sol = arbore[nod*2+1].sol;
        arbore[nod].m = arbore[nod*2+1].m;
        arbore[nod].p = arbore[nod*2+1].p;
    } else{
        arbore[nod].sol = arbore[nod*2].sol;
        arbore[nod].m = arbore[nod*2].m;
        arbore[nod].p = arbore[nod*2].p;
    }
}

void query(int nod,int left,int right,int start,int finish,int val)
{
    if(left <= start && right <= finish && val < v[arbore[nod].p] && maxim.sol < arbore[nod].sol){
        maxim.sol = arbore[nod].sol;
        maxim.p = arbore[nod].p;
        return;
    }
    if(left == right)
        return;
    int mij = (left+right)/2;
    if(start <= mij) query(nod*2,left,mij,start,finish,val);
    if (finish > mij) query(nod*2+1,mij+1,right,start,finish,val);
}

void citire()
{

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

        in>>x;
        v[i] = x;
        update(i,x,0,1,1,n);
    }
    in.close();
}

void solve()
{

    update(n,v[n],1,1,1,n);
    lg[n] = 1;
    pz[n] = -1;
    sol1 = 1;
    sol2 = n;
    for(int i = n-1 ; i >= 1 ; i--){
        maxim.sol = -1;
        query(1,1,n,i+1,n,v[i]);
        if(maxim.sol == -1) {
            lg[i] = 1;
            pz[n] = -1;
        }else{
            lg[i] = maxim.sol+1;
            pz[i] = maxim.p;
        }
        if(lg[i] > sol1){
            sol1 = lg[i];
            sol2 = i;
        }
        update(i,v[i],lg[i],1,1,n);
    }
    out<<sol1<<"\n";
    for(int i = 1 ; i <= sol1 ; i++){
        out<<v[sol2]<<" ";
        sol2 = pz[sol2];
    }
    out.close();
}

int main()
{

    citire();
    solve();
    return 0;
}