Pagini recente » Cod sursa (job #2413311) | Cod sursa (job #1822077) | Cod sursa (job #28510) | Cod sursa (job #1976677) | Cod sursa (job #2417443)
/* 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;
}