Cod sursa(job #2417443)

Utilizator dragomir_ioanDragomir Ioan dragomir_ioan Data 29 aprilie 2019 20:14:38
Problema Subsir crescator maximal Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.88 kb
/* scm */

#include <stdio.h>

#define MAXN 100000

int n, v[MAXN];
int ending_of_streak_of_length[MAXN+1], sol[MAXN+1], prec[MAXN+1];

int main() {
	freopen("scmax.in", "r", stdin);
	freopen("scmax.out", "w", stdout);

	scanf("%d", &n);
	for(int i=0; i<n; i++) scanf("%d", &v[i]);

	ending_of_streak_of_length[1] = 0;
	prec[0] = 0;

	int max_length = 1;

	for(int i=1; i<n; i++) {
		// find the longest streak that ends with a number less than v[i] (so we
		// can append v[i] to get a bigger streak)
		int lo = 1, hi = max_length, closest_under=0;
		while(lo <= hi) {
			int mid = (lo+hi) / 2;

			int midval = v[ending_of_streak_of_length[mid]];
			if(midval < v[i]) {
				closest_under = mid;
				lo = mid+1;
			} else {
				hi = mid-1;
			}
		}

		//if(closest_under == 0) {
		//	fprintf(stderr, "Creating new streak starting with v[%d]=%d\n", i, v[i]);
		//} else {
		//	fprintf(stderr, "Appending v[%d]=%d to streak of len %d ending on v[%d]=%d\n",
		//		i, v[i], closest_under, ending_of_streak_of_length[closest_under], v[ending_of_streak_of_length[closest_under]]);
		//}
		
		// append v[i] to the streak with length closest_under
		prec[i] = ending_of_streak_of_length[closest_under];

		// and make a new streak by appending v[i] if:
		//  a) we're making a max streak
		if(closest_under == max_length) {
			max_length++;
			ending_of_streak_of_length[max_length] = i;
		}
		//  b) v[i] is less than what we previously appended to this streak
		else if(v[ending_of_streak_of_length[closest_under+1]] > v[i]) {
			ending_of_streak_of_length[closest_under+1] = i;
		}
	}

	// recreate solution
	int sol[MAXN], pos = ending_of_streak_of_length[max_length];
	for(int i=max_length; i>0; i--) {
		sol[i] = v[pos];
		pos = prec[pos];
	}

	// print it
	printf("%d\n", max_length);
	for(int i=1; i<=max_length; i++) printf("%d ", sol[i]);

	return 0;
}