Cod sursa(job #2553143)

Utilizator PaulOrasanPaul Orasan PaulOrasan Data 21 februarie 2020 17:51:07
Problema Subsir crescator maximal Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <fstream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

ifstream fin("scmax.in");
ofstream fout("scmax.out");

const int NMAX=100010;

int n;
vector<pair<int,int> >v;
int poz[NMAX];
pair<int,int> arb[3*NMAX];
const pair<int,int> perInf(0,-1);
int sol[NMAX];
int pre[NMAX];
int initial[NMAX];
struct INTERVAL{
    int st,dr;
}interval[3*NMAX];
struct comparator{
    bool operator()(pair<int,int> a, pair<int,int> b){
        return a.first<b.first;
    }
};
void citire()
{
    fin>>n;
    pair<int,int>cont;
    cont.first=cont.second=0;
    v.reserve(NMAX);
    v.push_back(cont);
    for (int i=1; i<=n; i++){
        fin>>cont.first;
        cont.second=i;
        v.push_back(cont);
        initial[i]=cont.first;
    }
}
void stabilirePozitii()
{
    int j;
    for (int i=1; i<=n; i++){
        poz[v[i].second]=i;
        j=i+1;
        while (v[j].first==v[i].first && j<=n){
            poz[v[j].second]=i;
            j++;
        }
        i=j-1;
    }
}
void construireArbore(int rad, int st, int dr)
{
    if (st==dr){
        interval[rad].st=st;
        interval[rad].dr=dr;
        arb[rad].second=-1;
    }else if (st<dr){
        interval[rad].st=st;
        interval[rad].dr=dr;
        arb[rad].second=-1;
        int mij=(st+dr)/2;
        construireArbore(2*rad,st,mij);
        construireArbore(2*rad+1,mij+1,dr);
    }
}
void update(int rad, int a, int val,int pos)
{
    if (interval[rad].st==interval[rad].dr && interval[rad].st==a){
        arb[rad].first=val;
        arb[rad].second=pos;
    }else if (interval[rad].st<=a && interval[rad].dr>=a){
        update(2*rad,a,val,pos);
        update(2*rad+1,a,val,pos);
        if (arb[2*rad].first>arb[rad].first){
            arb[rad]=arb[2*rad];
        }
        if (arb[2*rad+1].first>arb[rad].first){
            arb[rad]=arb[2*rad+1];
        }
    }
}
pair<int,int> query(int rad, int st, int dr)
{
    if (interval[rad].st>=st && interval[rad].dr<=dr){
        return arb[rad];
    }
    if (interval[rad].st>dr || interval[rad].dr<st)
        return perInf;
    pair<int,int> a=query(2*rad,st,dr), b=query(2*rad+1,st,dr);
    return (a.first>b.first?a:b);
}
void rezolvare()
{
    pair<int,int> rezultat;
    for (int i=1; i<=n; i++){
        rezultat=query(1,1,poz[i]-1);
        sol[i]=rezultat.first+1;
        pre[i]=rezultat.second;
        update(1,poz[i],sol[i],i);
    }
}
void afisare()
{
    pair<int,int>maxim=query(1,1,n);
    fout<<maxim.first<<'\n';
    stack<int>q;
    while (maxim.second!=-1){
        q.push(maxim.second);
        maxim.second=pre[maxim.second];
    }
    while (!q.empty()){
        fout<<initial[q.top()]<<' ';
        q.pop();
    }
}
int main()
{
    citire();
    fin.close();
    sort(v.begin()+1,v.begin()+n+1,comparator());
    stabilirePozitii();
    construireArbore(1,1,n);
    rezolvare();
    afisare();
    fout.close();
    return 0;
}