Mai intai trebuie sa te autentifici.
Cod sursa(job #344138)
Utilizator | Data | 28 august 2009 17:16:22 | |
---|---|---|---|
Problema | Subsir crescator maximal | Scor | 100 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 2.05 kb |
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define N (1<<17)
#define P (1<<18)
using namespace std;
int n,v[N],nr[N],sortat[N],r;
int sol[N],x,poz;
int arb[P],best[N],inc,sf,maxim,rez,poz_f;
char line[N*11];
int u;
inline int digit(char x)
{
return '0' <= x && x <= '9';
}
void read()
{
scanf("%d\n",&n);
int i,c=1;
fgets(line+1, N*11, stdin);
for (i=1; i<=n; i++)
{
while (!digit(line[c])) ++c;
while (digit(line[c]))
{
v[i] = v[i]*10 + line[c] - '0';
++c;
}
}
}
int cbin(int x)
{
int i,step;
for (step=1; step<=r; step<<=1);
for (i=0; step; step>>=1)
if (i+step<=r && sortat[i+step]<=x)
i+=step;
return i;
}
void renumerotare()
{
memcpy(nr,v,sizeof(v));
sort(nr+1,nr+n+1);
int i,t;
for (i=1; i<=n; i++)
if (nr[i]!=nr[i-1])
sortat[++r]=nr[i];
for (i=1; i<=n; i++)
{
t=cbin(v[i]);
v[i]=t;
}
}
inline int maximum(int a,int b)
{
if (a>b)
return a;
return b;
}
void update(int nod,int st,int dr)
{
if (st==dr)
{
arb[nod]=maximum(x,arb[nod]);
return;
}
int t=(st+dr)/2;
if (poz<=t)
update(nod*2,st,t);
else
update(nod*2+1,t+1,dr);
arb[nod]=maximum(arb[nod*2],arb[nod*2+1]);
}
void query(int nod,int st,int dr)
{
if (inc<=st && dr<=sf)
{
if (maxim<arb[nod])
maxim=arb[nod];
return;
}
int t=(st+dr)/2;
if (inc<=t)
query(nod*2,st,t);
if (t<sf)
query(nod*2+1,t+1,dr);
}
void solve()
{
int i;
for (i=1; i<=n; i++)
{
maxim=0;
inc=1;
sf=v[i]-1;
if (sf)
query(1,1,r);
best[i]=maxim+1;
if (best[i]>rez)
{
rez=best[i];
poz_f=i;
}
x=best[i];
poz=v[i];
update(1,1,r);
}
printf("%d\n",rez);
}
void show()
{
int i;
while (rez)
{
sol[++u]=poz_f;
for (i=poz_f-1; i>=1; i--)
if (best[i]==rez-1)
{
poz_f=i;
break;
}
rez--;
}
for (i=u; i>=1; i--)
printf("%d ",sortat[v[sol[i]]]);
}
int main()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
read();
renumerotare();
solve();
show();
return 0;
}