Pagini recente » Cod sursa (job #2720792) | Rating Iamandi Iuri (Iuri) | Cod sursa (job #1710290) | Cod sursa (job #3203064) | Cod sursa (job #2512963)
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 100505;
const int INF = 2e9 + 5;
int N, A[NMAX], D[NMAX], aib[NMAX];
vector<int> allValues;
void compressPoints() {
for (int i = 1; i <= N; i++) {
allValues.push_back(A[i]);
}
sort(allValues.begin(), allValues.end());
allValues.resize(unique(allValues.begin(), allValues.end()) - allValues.begin());
for (int i = 1; i <= N; i++) {
A[i] = lower_bound(allValues.begin(), allValues.end(), A[i]) - allValues.begin() + 1;
}
}
int lsb(int x) {
return x ^ (x & (x - 1));
}
void updateValue(int pos, int value) {
for ( ; pos <= N; pos += lsb(pos)) {
aib[pos] = max(aib[pos], value);
}
}
int getMaximum(int pos) {
int result = 0;
for ( ; pos ; pos -= lsb(pos)) {
result = max(result, aib[pos]);
}
return result;
}
int main() {
freopen("scmax.in", "r", stdin);
freopen("scmax.out", "w", stdout);
scanf("%d", &N);
for (int i = 1; i <= N; i++) {
scanf("%d", &A[i]);
}
compressPoints();
int longestIncreasing = 0;
for (int i = 1; i <= N; i++) {
D[i] = getMaximum(A[i] - 1) + 1;
updateValue(A[i], D[i]);
longestIncreasing = max(longestIncreasing, D[i]);
}
vector<int> recons;
recons.reserve(longestIncreasing);
int prevValue = INF, currentPos = N;
while (currentPos) {
if (A[currentPos] < prevValue && longestIncreasing == D[currentPos]) {
recons.push_back(A[currentPos]);
prevValue = A[currentPos];
longestIncreasing--;
}
currentPos--;
}
reverse(recons.begin(), recons.end());
printf("%d\n", (int) recons.size());
for (auto& x : recons) {
printf("%d ", allValues[x - 1]);
}
printf("\n");
return 0;
}