Cod sursa(job #2487030)

Utilizator vali_27Bojici Valentin vali_27 Data 3 noiembrie 2019 20:00:22
Problema Subsir crescator maximal Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.31 kb
#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;


int v[NMAX],a[NMAX*3+200],n,len[NMAX];
pair <int , int >p[NMAX];

FILE *fin = fopen("in.in","r");
FILE *fout= fopen("out.out","w");

void update(int nod,int st,int dr,int poz,int val)
{
    if(st == dr)
        a[nod] = val;
    else
    {
        int d = (st + dr)/2;
        if(poz <= d)
            update(nod*2, st, d, poz, val);
        else
            update(nod*2+1, d+1, dr, poz, val);

        a[nod] = max(a[nod*2],a[nod*2+1]);
    }
}

void query(int nod,int st,int dr,int x,int y ,int &rez)
{
    if( st >= x && dr <= y)
        rez = max(rez,a[nod]);
    else
    {
        int d = (st+dr)/2;
        if(d >=x )
            query(nod*2, st, d, x, y, rez);
        if(d < y )
            query(nod*2+1, d+1, dr, x, y, rez);
    }
}

bool comp(pair <int ,int > p1 , pair <int , int > p2)
{
    if(p1.first == p2.first)
        return p1.second > p2.second; // strict crecator/ca sa nu se repete nr =>  p.second mai mare trb sa fie in fata

    return p1.first < p2.first;
}

void citire()
{
    fscanf(fin,"%d",&n);
    for(int i=1;i<=n;++i) // ordonez vectorul dupa valoare si index ** vezi comp();
        {
            fscanf(fin,"%d",&v[i]);
            p[i].first = v[i];
            p[i].second = i;
        }
    sort(p+1,p+n+1,comp);

    for(int i=1;i<=n;++i)
    {
        int maxx = 0;

        query(1,1,n,1,p[i].second,maxx); // cate nr mai mici decat nr la indexul p[i].second

        update(1,1,n,p[i].second,maxx+1); //update la poz p[i].second cu maxx de sus + 1;  un fel de lmax[i] = 1 + Lmax

        maxx = 0;
        query(1, 1, n, 1, p[i].second, maxx); //cat de lunga e cea mai lunga subsecv crescatoare de la 1 la p[i].second
        len[p[i].second] = maxx;
    }

}

void sol()
{
    list <int> solutie;
    int Lmax = a[1],fost_i,i=n;

    fprintf(fout,"%d\n",Lmax);

    while(i && len[i] != Lmax)i--;
    solutie.push_front(v[i]);
    Lmax--;
    fost_i = i;

    while(i && Lmax)
    {
        if(len[i] == Lmax && v[i] < v[fost_i])
        {
            Lmax--;
            fost_i = i;
            solutie.push_front(v[i]);
        }
        i--;
    }

    for(int i : solutie)fprintf(fout,"%d ",i);
}

int main()
{
    citire();
    sol();

}