Cod sursa(job #1147359)

Utilizator vladtarniceruVlad Tarniceru vladtarniceru Data 19 martie 2014 19:25:34
Problema Subsir crescator maximal Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int buff_size = 1024 * 1024;
char buff[buff_size];

inline bool digit(const char &a) {
	if ('0' <= a && a <= '9')
		return true;
	return false;
}

inline void getInt(int &a) {
	a = 0; static int i = buff_size - 1;
	if (++i == buff_size)
		fread(buff, 1, buff_size, stdin), i = 0;
	while (!digit(buff[i]))
		if (++i == buff_size)
			fread(buff, 1, buff_size, stdin), i = 0;
	while (digit(buff[i])) {
		a = a * 10 + buff[i] - '0';
		if (++i == buff_size)
			fread(buff, 1, buff_size, stdin), i = 0;
	}
}

const int MaxN = 100 * 1000 + 5;

int n, dp[MaxN];
int v[MaxN], a[MaxN], s[MaxN];

inline int norm(int val) {
	int i = 0, cnt = 1 << 16;
	for (; cnt; cnt >>= 1)
		if (i + cnt <= n && s[i + cnt] <= val)
			i += cnt;
	return i;
}

int aib[MaxN];

inline void add(int pos, int val) {
	for (int i = pos; i <= n; i = (i | (i - 1)) + 1)
		aib[i] = max(aib[i], val);
}

inline int get(int pos) {
	int r = 0;
	for (int i = pos; i >= 1; i = i & (i - 1))
		r = max(r, aib[i]);
	return r;
}

inline void write(int pos) {
	for (int i = pos; i >= 1; --i)
		if (a[i] < a[pos] && dp[i] + 1 == dp[pos]) {
			write(i);
			break;
		}
	printf("%d ", v[pos]);
}

int main() {
	freopen("scmax.in", "r", stdin);
	freopen("scmax.out", "w", stdout);
	getInt(n);
	for (int i = 1; i <= n; ++i)
		getInt(v[i]), s[i] = a[i] = v[i];
	
	sort(s + 1, s + n + 1);
	for (int i = 1; i <= n; ++i)
		a[i] = norm(a[i]);

	int sol = 0, pos;
	for (int i = 1; i <= n; ++i) {
		dp[i] = get(a[i] - 1) + 1;
		add(a[i], dp[i]);
		if (sol < dp[i]) {
			sol = dp[i];
			pos = i;
		}
	}
	
	printf("%d\n", sol);
	write(pos); printf("\n");
}