Pagini recente » Cod sursa (job #911963) | preONI 2008 - Clasament general, Clasa a 10-a | Cod sursa (job #591904) | Cod sursa (job #1600245) | Cod sursa (job #447222)
Cod sursa(job #447222)
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;
#define FILE_IN "scmax.in"
#define FILE_OUT "scmax.out"
typedef unsigned int uint;
#define NONE N
int N;
int* aib;
uint* sir;
uint* compact;
int* lung;
int* pre;
void aib_setmax(int index, int value)
{
while (index <= N)
{
if (lung[value] > lung[aib[index]])
aib[index] = value;
index += (index & -index);
}
}
int aib_getmax(int index)
{
int best = NONE;
while (index)
{
if (lung[aib[index]] > lung[best])
best = aib[index];
index &= (index-1);
}
return best;
}
int main()
{
ifstream fisIn(FILE_IN);
ofstream fisOut(FILE_OUT);
fisIn >> N;
sir = new uint[N];
for (int i=0; i<N; i++) fisIn >> sir[i];
compact = new uint[N];
copy(sir, sir+N, compact);
sort(compact, compact+N);
for (int i=0; i<N; i++)
sir[i] = 1+(lower_bound(compact, compact+N, sir[i])-compact);
lung = new int[N+1];
pre = new int[N+1];
lung[NONE] = 0;
pre[NONE] = -1;
aib = new int[N+1];
fill(aib, aib+N+1, NONE);
for (int i=0; i<N; i++)
{
int best = aib_getmax(sir[i]-1);
lung[i] = lung[best]+1;
pre[i] = best;
aib_setmax(sir[i], i);
}
int best = aib_getmax(N);
int lungime = lung[best];
uint* rez = new uint[lungime];
uint* ptr = rez+lungime-1;
while (best != NONE)
{
*(ptr--) = compact[sir[best]-1];
best = pre[best];
}
fisOut << lungime << "\n";
for (int i=0; i<lungime; i++)
{
if (i) fisOut << ' ';
fisOut << rez[i];
}
fisOut << '\n';
}