Cod sursa(job #2578513)

Utilizator Rares31100Popa Rares Rares31100 Data 11 martie 2020 10:52:31
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <bits/stdc++.h>

using namespace std;

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

int n,a[100001];
int pozT[100001];
int num[100001],sizeNum,tree[100001];
int val[100001],urm[100001];
int sol[100001],sizeSol;

void buildTree()
{
    for(int i=1;i<=n;i++)
        num[i]=a[i];

    sort(num+1,num+1+n);

    sizeNum++;
    for(int i=2;i<=n;i++)
        if(num[sizeNum]!=num[i])
            num[++sizeNum]=num[i];

    for(int i=1;i<=n;i++)
        pozT[i]=lower_bound(num+1,num+1+sizeNum,a[i])-num;
}

void update(int poz,int P)
{
    while(poz<=sizeNum)
    {
        if(val[ tree[poz] ]<=val[P])
            tree[poz]=P;
        else
            break;

        poz+=poz&-poz;
    }
}

int maxim(int poz)
{
    int P=tree[poz];

    while(poz)
    {
        if(val[ tree[poz] ]>=val[P])
            P=tree[poz];

        poz-=poz&-poz;
    }

    return P;
}

int main()
{
    in>>n;

    for(int i=1;i<=n;i++)
        in>>a[i];

    buildTree();

    val[1]=1;
    update(pozT[1],1);

    for(int i=2;i<=n;i++)
    {
        urm[i]=maxim(pozT[i]-1);
        val[i]=val[ urm[i] ]+1;
        update(pozT[i],i);
    }

    int St=0;

    for(int i=1;i<=n;i++)
        if(val[i]>val[St])
            St=i;

    while(St)
    {
        sol[++sizeSol]=a[St];
        St=urm[St];
    }

    out<<sizeSol<<'\n';

    for(int i=sizeSol;i>=1;i--)
        out<<sol[i]<<' ';

    return 0;
}