Cod sursa(job #2512963)

Utilizator radustn92Radu Stancu radustn92 Data 22 decembrie 2019 01:26:57
Problema Subsir crescator maximal Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#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;
}