Pagini recente » Cod sursa (job #1406125) | Cod sursa (job #3038209) | Cod sursa (job #728956) | Cod sursa (job #747187) | Cod sursa (job #568164)
Cod sursa(job #568164)
#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;
}