Cod sursa(job #568164)

Utilizator dicu_dariaDaria Dicu dicu_daria Data 30 martie 2011 21:20:37
Problema Subsir crescator maximal Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.25 kb
#include <fstream>
#include <algorithm>
#define zeros(x) (((x-1)^x)&x)
#define MAX 100005
using namespace std;
int aib[MAX],a[MAX],b[MAX],up[MAX],p[MAX],D[MAX],n;
void update(int x,int p)
{
    int i;
    for(i=x;i<=n;i+=zeros(i))
        if(D[aib[i]]<D[p]) aib[i]=p;
}
int query(int x)
{
    int mx=0,i;
    for(i=x;i>0;i-=zeros(i))
        if(D[mx]<D[aib[i]]) mx=aib[i];
    return mx;
}
int main()
{
    int m=1,i,best;
    ifstream fi("scmax.in");
    ofstream fo("scmax.out");
    fi>>n;
    for(i=1;i<=n;i++)
    {
        fi>>a[i];
        b[i]=a[i];
    }
    sort(b+1,b+n+1);
    for(i=1;i<=n;i++)
        if(b[m]!=b[i]) b[++m]=b[i];
    //in vectorul b am fiecare element in ord cresc
    for(i=1;i<=n;i++)
        p[i]=lower_bound(b+1,b+m+1,a[i])-b;
    //in p am pozitia elementului i in b(al catelea e ca marime)
    for(i=1;i<=n;i++)
    {
        up[i]=query(p[i]-1);//drumul maxim al elementelor mai mici ca marime
        D[i]=D[up[i]]+1;
        update(p[i],i); //updatez intervalele care au primele p[i] elem
    }
    best=0; m=0;
    for(i=1;i<=n;i++)
        if(D[i]>D[best]) best=i;
    fo<<D[best]<<"\n";
    for(i=best;i;i=up[i])
        b[++m]=a[i];
    for(i=m;i>0;i--) fo<<b[i]<<" ";
    return 0;
}