Cod sursa(job #2549526)

Utilizator PaulOrasanPaul Orasan PaulOrasan Data 17 februarie 2020 19:19:59
Problema Subsir crescator maximal Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.12 kb
#include <fstream>
#include <stack>
#include <queue>
using namespace std;

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

const int NMAX=100010, inf=100000000;
int n, v[NMAX], best[NMAX];
int arb[NMAX*3];
int poz[NMAX*3];
int pre[NMAX];
struct INTERVAL{
    int st,dr;
}interval[NMAX*3];
void citire()
{
    fin>>n;
    for (int i=1; i<=n; i++){
        best[i]=inf;
        fin>>v[i];
    }
}
void construireArbore(int rad, int st, int dr)
{
    if (st==dr){
        interval[rad].st=st;
        interval[rad].dr=dr;
        arb[rad]=best[st];
        poz[rad]=st;
    }else if (st<dr){
        interval[rad].st=st;
        interval[rad].dr=dr;
        int mij=(st+dr)/2;
        construireArbore(2*rad,st,mij);
        construireArbore(2*rad+1,mij+1,dr);
        if (arb[2*rad]<arb[2*rad+1]){
            arb[rad]=arb[2*rad];
            poz[rad]=poz[2*rad];
        }else{
            arb[rad]=arb[2*rad+1];
            poz[rad]=poz[2*rad+1];
        }
    }
}
void update(int rad, int a, int b)
{
    if (interval[rad].st==interval[rad].dr && interval[rad].st==a){
        arb[rad]=b;
    }else if (interval[rad].st<=a && a<=interval[rad].dr){
        update(2*rad,a,b);
        update(2*rad+1,a,b);
        if (arb[2*rad]>arb[2*rad+1]){
            arb[rad]=arb[2*rad];
            poz[rad]=poz[2*rad];
        }else{
            arb[rad]=arb[2*rad+1];
            poz[rad]=poz[2*rad+1];
        }
    }
}
pair<int,int> query(int rad, int st, int dr, int x)
{
    if (interval[rad].st>=st && interval[rad].dr<=dr){
        if (v[poz[rad]]>=v[x]){
            return pair<int,int>(inf,-1);
        }
        return pair<int,int>(arb[rad],poz[rad]);
    }else if (interval[rad].st>dr || interval[rad].dr<st){
        return pair<int,int>(inf,-1);
    }
    pair<int,int> a,b;
    a=query(2*rad,st,dr,x);
    b=query(2*rad,st,dr,x);
    return (a.first>b.first?a:b);
}
void BFS(int rad)
{
    queue<int>q;
    q.push(rad);
    int k;
    while (!q.empty()){
        k=q.front();
        q.pop();
        if (interval[k].st!=0){
            fout<<interval[k].st<<' '<<interval[k].dr<<' '<<arb[rad]<<' '<<poz[rad]<<'\n';
            q.push(2*k);
            q.push(2*k+1);
        }
    }
}
void rezolvare()
{
    best[1]=1;
    update(1,1,1);
    pair <int,int> x;
    for (int i=2; i<=n; i++){
        x=query(1,1,i-1,i);
        if (x.second==-1){
            best[i]=1;
        }else{
            best[i]=x.first+1;
            pre[i]=x.second;
        }
       // fout<<i-1<<'\n';
      //  BFS(1);
        update(1,i,best[i]);
    }
}
void afisare()
{
    int mx=0, pozMx=0;
    for (int i=1; i<=n; i++){
        if (best[i]>mx){
            mx=best[i];
            pozMx=i;
        }
    }
    stack<int>q;
    while (pozMx!=0){
        q.push(pozMx);
        pozMx=pre[pozMx];
    }
    fout<<mx<<'\n';
    while (!q.empty()){
        fout<<v[q.top()]<<' ';
        q.pop();
    }
}
int main()
{
    citire();
    fin.close();
    construireArbore(1,1,n);
    rezolvare();
   // BFS(1);
    afisare();
    fout.close();
    return 0;
}