Pagini recente » Cod sursa (job #2774572) | Cod sursa (job #172127) | Cod sursa (job #3038006) | Cod sursa (job #2102184) | Cod sursa (job #705479)
Cod sursa(job #705479)
#include <cstdio>
#include <algorithm>
#define infile "scmax.in"
#define outfile "scmax.out"
#define n_max 100005
#define zeros(x) ((x^(x-1))&x)
using namespace std;
int lst[n_max], v[n_max], a[n_max], prev[n_max], Lg[n_max];
int AIB[n_max];
int N;
void citeste()
{
freopen(infile, "r", stdin);
scanf("%d", &N);
for (int i = 1; i <= N; ++i)
{
scanf("%d", &a[i]);
v[i] = lst[i] = a[i];
}
fclose(stdin);
}
void update(int x, int poz)
{
for(; x<=N; x += zeros(x))
if(Lg[AIB[x]] < Lg[poz])
AIB[x] = poz;
}
int query(int x)
{
int pmax = 0;
for(; x; x -= zeros(x))
if(Lg[AIB[x]] > Lg[pmax])
pmax = AIB[x];
return pmax;
}
void rezolva()
{
sort(lst+1, lst+N+1);//sortez valorile
for(int i=1; i<=N; ++i)//normalizez valorile in vectorul v
v[i] = lower_bound(lst+1, lst+N+1, v[i]) - lst;
for(int i=1; i<=N; ++i)
{
prev[i] = query(v[i]-1);//caut pozitia elementului < v[i] care are Lg maxim
Lg[i] = Lg[prev[i]] + 1;//actualizez lungimea
update(v[i], i);//actualizez intervalul...daca Lg[i] este c.m.mare pe intervalul [1, v[i]]
}
int Best = 0;
for(int i=1;i<=N; ++i)
if(Lg[i] > Lg[Best])//caut pozitia elementului cu Lg maxim
Best = i;
lst[0] = 0;
for(; Best; Best = prev[Best])//merg din fiu in tata
lst[++lst[0]] = a[Best];//salvez in solutie valoarea initiala
}
void afiseaza()
{
freopen(outfile, "w", stdout);
printf("%d\n", lst[0]);
for(int i = lst[0]; i; --i)
printf("%d ", lst[i]);
printf("\n");
fclose(stdout);
}
int main(void)
{
citeste();
rezolva();
afiseaza();
return 0;
}