Cod sursa(job #2759471)

Utilizator NeacsuMihaiNeacsu Mihai NeacsuMihai Data 18 iunie 2021 00:12:28
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
/*
    Am adaugat o parcurgere experimentala a AIB-ului
*/

#include <iostream>
#include <fstream>
#include <algorithm>

#define NMAX 100000 //o suta de mii
#define INFINIT 2000000001 //doua miliarde unu

using namespace std;

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

int N;
int aib[NMAX + 1];
int bst[NMAX + 1];
int afis[NMAX + 1];

struct element{
    int val;
    int poz;
}v[NMAX + 1];

int comparare(element A, element B){
    return A.val < B.val;
}

inline void update(int poz, int val){
    //poz nu o sa contina nimic inainte
    //garantat

    aib[poz] = max(aib[poz], val);

    for(int j = 1; j <= N; j = j * 2){
        if( (poz & j) == 0){ ///neaparat nevoie de paranteze!!!!!! altfel face altceva!!

            if(poz + j <= N){
                aib[poz + j] = max(aib[poz + j], val);
            }
        }
        else {
            poz = poz - j; //il fac 0
        }
    }

    /*
    for(int i = poz; i <= N; i += i & (-i)){
        aib[i] = max(aib[i], val);
    }
    */
}

inline int query(int poz){
    int mx = 0;
    int aux = poz;

    for(int j = 1; j <= aux; j = j * 2){
        if( (poz & j) != 0){ ///neaparat nevoie de paranteze!!!!!! altfel face altceva!!

            mx = max(mx, aib[poz]);
            poz = poz - j; //il fac 0

        }
    }

    /*
    for(int i = poz; i >= 1; i -= i & (-i)){
        mx = max(mx, aib[i]);
    }
    */

    return mx;
}

int main()
{
    fin >> N;

    for(int i = 1; i <= N; i++){
        fin >> v[i].val;
        v[i].poz = i;
    }

    sort(v + 1, v + N + 1, comparare);

    int rspMx = 0;
    for(int i = 1; i <= N; i++){
        bst[i] = 1 + query(v[i].poz - 1);

        if(i < N && v[i].val != v[i + 1].val){
            for(int j = i; j >= 1 && v[j].val == v[i].val; j--){
                update(v[j].poz, bst[j]);
            }
        }

        rspMx = max(rspMx, bst[i]);
    }

    fout << rspMx << "\n";

    int aux = rspMx;
    int cr = INFINIT;
    for(int i = N; i >= 1 && aux >= 1; i--){
        if(v[i].val < cr && bst[i] == aux){
            afis[aux] = v[i].val;
            cr = v[i].val;
            aux--;
        }
    }

    for(int i = 1; i <= rspMx; i++){
        fout << afis[i] << ' ';
    }

    return 0;
}