Pagini recente » Cod sursa (job #1196278) | Cod sursa (job #1673366) | Cod sursa (job #416515) | Cod sursa (job #263947) | Cod sursa (job #1445648)
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <stack>
#define _submit
#ifdef _submit
#define InFile "scmax.in"
#define OutFile "scmax.out"
#else
#define InFile "fis.in"
#define OutFile "fis.out"
#endif
#define MAXN 100010
#define MAXARB 300030
int sequence[MAXN];
int sortedSeq[MAXN];
int prev[MAXN];
std::pair<int,int> arbInt[MAXARB];
int arbSz;
int gudSz(int N) {
int p = 1;
while (p < N)
p <<= 1;
return p;
}
void vidareArb() {
for (int i = arbSz; i < (arbSz << 1); i++)
arbInt[i] = { 0, i - arbSz + 1 };
for (int i = arbSz - 1; i>0; i--)
arbInt[i] = std::max(arbInt[i << 1], arbInt[(i << 1) + 1]);
}
void update(int pos, int x) {
pos += arbSz - 1;
arbInt[pos].first = x;
pos >>= 1;
while (pos) {
std::pair<int,int> aux = std::max(arbInt[pos << 1], arbInt[(pos << 1) + 1]);
if (aux.first == arbInt[pos].first)
break;
arbInt[pos] = aux;
pos >>= 1;
}
}
std::pair<int,int> query(int left, int right) {
left += arbSz - 1;
right += arbSz - 1;
std::pair<int, int> r = { 0, 0 };
while (left <= right) {
r = std::max(r, std::max(arbInt[left], arbInt[right]));
left = (left + 1) << 1;
right = (right - 1) << 1;
}
return r;
}
int main() {
assert(freopen(InFile, "r", stdin));
assert(freopen(OutFile, "w", stdout));
int N;
scanf("%d", &N);
arbSz = gudSz(N);
vidareArb();
for (int i = 1; i <= N; i++) {
scanf("%d", &sequence[i]);
sortedSeq[i] = sequence[i];
}
std::sort(sortedSeq + 1, sortedSeq + N + 1);
for (int i = 1; i <= N; i++) {
int left = 1;
int right = N;
int pos = -1;
int bound = -1;
while (left <= right) {
int mid = (left + right) >> 1;
if (sortedSeq[mid] == sequence[i] && arbInt[mid + arbSz - 1].first == 0) {
pos = mid;
right = mid - 1;
}
else if (sequence[i] <= sortedSeq[mid])
right = mid - 1;
else {
left = mid + 1;
bound = mid;
}
}
assert(pos != -1);
if (bound == -1) {
update(pos, 1);
prev[pos] = 0;
}
std::pair<int,int> bestmax = query(1, bound);
update(pos, bestmax.first + 1);
prev[pos] = bestmax.second;
}
std::pair<int, int> maxlen = { 0, 0};
for (int i = arbSz; i < arbSz + N; i++) {
if (arbInt[i] > maxlen)
maxlen = arbInt[i];
}
printf("%d\n", maxlen.first);
std::stack<int> S;
int curNod = maxlen.second;
while (curNod) {
S.push(curNod);
curNod = prev[curNod];
}
while (!S.empty()) {
printf("%d ", sortedSeq[S.top()]);
S.pop();
}
return 0;
}