Cod sursa(job #2026520)

Utilizator Johnny07Savu Ioan-Daniel Johnny07 Data 24 septembrie 2017 15:55:47
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("scmax.in");
ofstream g("scmax.out");

int a[100010],sol[100010],i,k,n,soll[100010];

struct st
{
    int dp, ma;
}tree[400010];


void build (int nod, int st, int dr)
{
    int mid=st+dr;
    mid/=2;
    if (st!=dr)
    {
        build (nod*2, st, mid);
        build (nod*2+1, mid+1, dr);
        if (tree[nod*2].dp>tree[nod].dp) {tree[nod].dp=tree[nod*2].dp;tree[nod].ma=tree[nod*2].ma;}
        if (tree[nod*2].dp==tree[nod].dp) {tree[nod].dp=tree[nod*2].dp;tree[nod].ma=min(tree[nod].ma,tree[nod*2].ma);}
        if (tree[nod*2+1].dp>tree[nod].dp) {tree[nod].dp=tree[nod*2+1].dp;tree[nod].ma=tree[nod*2+1].ma;}
        if (tree[nod*2+1].dp==tree[nod].dp) {tree[nod].dp=tree[nod*2+1].dp;tree[nod].ma=min(tree[nod].ma,tree[nod*2+1].ma);}
    }
    else
    {
        tree[nod].ma=a[st];
        if (st==1) tree[nod].dp=1;
    }
}

void solve (int nod, int xs, int xd, int st, int dr)
{
    int mid=st+dr;
    mid/=2;
    if (st!=dr)
    {
    if (tree[nod*2].ma<a[i]) sol[i]=max(sol[i],tree[nod*2].dp);
    else solve (nod*2, xs, min(mid, xd), st, mid);
    if (xd>mid)
    {
        if (tree[nod*2+1].ma<a[i]) sol[i]=max(sol[i],tree[nod*2+1].dp);
        else solve (nod*2+1, xs, xd, mid+1, dr);
    }
    }
    else
    {
        if (tree[nod].ma<a[i]) sol[i]=max(sol[i],tree[nod].dp);
    }

}

void update (int nod, int st, int dr)
{
    int mid=st+dr;
    mid/=2;
    if (st!=dr)
    {
        if (i<=mid) update (nod*2, st, mid);
        else update (nod*2+1, mid+1, dr);
        if (tree[nod*2].dp>tree[nod].dp) {tree[nod].dp=tree[nod*2].dp;tree[nod].ma=tree[nod*2].ma;}
        if (tree[nod*2].dp==tree[nod].dp) {tree[nod].dp=tree[nod*2].dp;tree[nod].ma=min(tree[nod].ma,tree[nod*2].ma);}
        if (tree[nod*2+1].dp>tree[nod].dp) {tree[nod].dp=tree[nod*2+1].dp;tree[nod].ma=tree[nod*2+1].ma;}
        if (tree[nod*2+1].dp==tree[nod].dp) {tree[nod].dp=tree[nod*2+1].dp;tree[nod].ma=min(tree[nod].ma,tree[nod*2+1].ma);}
    }
    else
    {
        tree[nod].dp=sol[i];
    }
}

int main()
{
    f>>n;
    sol[1]=1;
    for (i=1;i<=n;i++)
    {
        f>>a[i];
    }
build (1, 1, n);
//cout<<tree[1].ma;
    i=2;
    for (i=2;i<=n;i++){

        if (tree[1].ma<a[i]) sol[i]=tree[1].dp;
        else solve(1, 1, i, 1, n);
       // cout<<" "<<sol[i];
        sol[i]++;
        update(1, 1, n);
    }
    int ma=0;
    int x=2000000001;
    int auxma=0;
for (i=1;i<=n;i++) ma=max(ma,sol[i]);
auxma=ma;
for (i=n;i>=1;i--)
{
    if (sol[i]==ma && a[i]<x) {ma--;x=a[i];soll[ma+1]=a[i];}
}
g<<auxma<<"\n";
for (i=1;i<=auxma;i++) g<<soll[i]<<" ";


    return 0;
}