Pagini recente » Cod sursa (job #1758117) | Cod sursa (job #285590) | Cod sursa (job #538433) | Cod sursa (job #2066975) | Cod sursa (job #532941)
Cod sursa(job #532941)
/*
x[i] -> pozitia in vectorul v pe care se termina un subsir de lungime i.
dintre toate pozitiile posibile, este stocata cea in care v[i] minim.
pentru numerele de pana acum.
Pentru fiecare pozitie din vectorul v (1,2,...,n)
se gaseste cel mai mare l (lungimea maxima de subsir la care poate fi
atasat)
astfel incat v[x[j]] (valoarea elementului la care atasez) sa fie mai
mica decat v[i] (valoarea elementului curent)
noii valori i se marcheaza pozitia in x la lungimea maxima posibila.
in nx se retine lungimea maxima obtinuta
chiar daca un numar nu mareste lungimea subsirurilor, poate micsora valoarea
de pe o anumita lungime (facilitand formarea viitoarelor subsiruri; chiar
daca noua valoare ar putea sa se lege crescator de urmatoarele, nu se poate
deoarece apare pe o pozitie mai mare decat acestea si deci nu mai formeaza
subsir)
dar valorile din v indicate din x sunt in ordine crescatoare, din moment ce
prin imbunatatirea valorii de pe o lungime, aceasta ramane mai mica decat
valorile de pe urmatoarele pozitii.
noua valoare pusa pentru o lungime va fi sigur mai mica decat cea existenta,
pentru ca altfel ar fi fost pusa legata de aceasta, pe o pozitie mai mare.
pred[i] -> elementul precedent din subsirul ales pentru elementul v[i]
pred[i] = x[j]
*/
#include <cstdio>
const int N = 100001;
int v[N],n;
int x[N],nx=0;
int pred[N];
inline int max (int a, int b)
{
return (a>b)?a:b;
}
void citire()
{
scanf("%i",&n);
for (int i = 1; i <= n; ++i)
scanf("%i",&v[i]);
}
int lung_max(int i)//lungimea maxima de subsir in care sfarsitul indicat de x este mai mic decat noua valoare v[i].
{
int l = 0;
for (int pas = 1<<17; pas > 0; pas /= 2)
if ((l+pas <= nx)&&(v[x[l+pas]] < v[i]))
l += pas;
return l;
}
void calculare_x()
{
int l;
for (int i = 1; i <= n; ++i)
{
l = lung_max(i);
x[l+1] = i;
nx = max (nx,l+1);
pred[i] = x[l];
}
}
void afisare(int poz)
{
if (pred[poz] != 0)
afisare(pred[poz]);
printf("%i ",v[poz]);
}
int main()
{
freopen("scmax.in","r",stdin);
freopen("scmax.out","w",stdout);
citire();
calculare_x();
printf("%i\n",nx);
afisare(x[nx]);
return 0;
}