Pagini recente » Cod sursa (job #2700501) | Cod sursa (job #2364632) | Cod sursa (job #2445128) | Cod sursa (job #1874526) | Cod sursa (job #2330599)
///ALGORITMUL ROBINSON-SCHENSTED-KNUTH
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("scmax.in");
ofstream out("scmax.out");
const int MAXN = 100001;
int a[MAXN];
int b[MAXN]; //b[i] = pozitia primului element din sir pt care subsirul care incepe cu acel element are lg i
int poz[MAXN]; //poz[i] = pozitia elementului care urmeaza dupa a[i] in cel mai lung subsir crescator care incepe cu a[i]
int N, lmax;
void citire()
{
in >> N;
for(int i = 1; i <= N; ++i)
in >> a[i];
}
int caut(int p, int u, int x)
{
while(p <= u)
{
int m = (p + u) / 2;
if(x < a[b[m]])
p = m + 1;
else
u = m - 1;
}
return p - 1;
}
void subsir()
{
lmax = 1;
poz[N] = 0;
b[1] = N;
for(int i = N - 1; i >= 1; --i)
{
//se cauta cea mai mare lungime a unui subsir strict crescator la care sa intre a[i]
int k = caut(1, lmax, a[i]);
poz[i] = b[k]; //dupa a[i] urmeaza a[b[k]]
++k; //am adaugat si pe a[i]
if(k > lmax)
{
lmax = k;
b[k] = i;
}
else
if(a[b[k]] < a[i])
b[k] = i;
}
}
void tipar()
{
out << lmax << '\n';
for(int i = b[lmax]; i > 0; i = poz[i])
out << a[i] << ' ';
}
int main()
{
citire();
subsir();
tipar();
return 0;
}