Cod sursa(job #1059118)

Utilizator alexpascadiAlexandru Pascadi alexpascadi Data 16 decembrie 2013 10:42:55
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include <stdio.h>
#include <algorithm>
using namespace std;

const int N=100001;
int t[N],d[N],v[N],ord[N],norm[N],pred[N],n,nord;

int caut (int val)
{
    int sol=0, pas=1<<30;
    while(pas)
    {
        if(sol+pas<=nord && ord[sol+pas]<val) sol+=pas;
        pas>>=1;
    }
    return sol+1;
}

int query(int p)
{
    int poz=0;
    while(p>0)
    {
        if(d[t[p]]>d[poz]) poz=t[p];
        p-=p&-p;
    }
    return poz;
}

void update(int p, int i)
{
    while(p<=n)
    {
        if(d[i]>d[t[p]]) t[p]=i;
        p+=p&-p;
    }
}

int main()
{
    FILE *in,*out;
    in=fopen("scmax.in","r");
    out=fopen("scmax.out","w");
    int i;
    nord=1;

    fscanf(in,"%d",&n);
    for(i=1;i<=n;i++) t[i]=d[i]=pred[i]=0;
    for(i=1;i<=n;i++)
    {
        fscanf(in,"%d",&v[i]);
        ord[i]=v[i];
    }
    sort(ord+1,ord+n+1);
    for(i=2;i<=n;i++)
    {
        if(ord[i]>ord[nord]) ord[++nord]=ord[i];
    }
    for(i=1;i<=n;i++)
        norm[i]=caut(v[i]);

    for(i=1;i<=n;i++)
    {
        pred[i]=query(norm[i]-1);
        d[i]=d[pred[i]]+1;
        update(norm[i],i);
    }

    int best=1;
    for(i=1;i<=n;i++)
        if(d[best]<d[i]) best=i;

    fprintf(out,"%d\n",d[best]);
    nord=0;
    for(i=best;i>0;i=pred[i])
        ord[++nord]=v[i];

    for(i=nord;i>0;i--)
        fprintf(out,"%d ",ord[i]);

    return 0;
}