Pagini recente » Cod sursa (job #1968564) | Cod sursa (job #1462433) | Cod sursa (job #2842712) | Cod sursa (job #2641164) | Cod sursa (job #489323)
Cod sursa(job #489323)
/* 1:40 so far */
#include <stdio.h>
#include <stdlib.h>
int n;
int X[100010];
int S[100010]; /* X[S[i]] e array-ul sortat */
int sortme(const void * a, const void * b) {
return X[*((int *)a)] - X[*((int*)b)];
}
int SS[100010]; /* SS[i] e pozitia lui X[i] in arrayul sortat */
int smallest_tail[100010];
int P[100010]; /* P[i] = elementul anterior elementului cu indicele i, pentru scrierea rezultatelor */
int A[100010]; /* arbore indexat binar, contine lungimea maxima care se poate poate atinge doar cu elemente de valoare */
#define DEBUG(x) if (0) { fprintf(stderr, x); fflush(stderr); }
int getmax(int order) { /* order can be 1 at the smallest */
if (order==0) return 0;
int max = A[order];
do {
order -= (order ^ (order - 1)) & order;
if (order>0 && A[order]>max) max = A[order];
} while (order>0);
return max;
}
void add(int order, int mod) {
while (order<=n) {
if (A[order]<mod) A[order] = mod;
order += (order ^ (order-1)) & order;
DEBUG(",\n");
}
}
void backwrite(int lp) {
if (P[lp]!=-1)
backwrite(P[lp]);
printf("%d ", X[lp]);
}
int temp[100010];
void merges(int * a, int i, int j) {
int k, l, x, m;
if (i>=j) return;
m = (i + j) / 2;
merges(a, i, m);
merges(a, m+1, j);
k = i;
l = m + 1;
x = i;
while (k<=m || l<=j) {
if (k<=m && l<=j) {
if (X[a[k]] < X[a[l]]) {
temp[x] = a[k];
x++; k++;
} else {
temp[x] = a[l];
x++; l++;
}
} else if (k<=m) {
temp[x] = a[k];
x++; k++;
} else {
temp[x] = a[l];
x++; l++;
}
}
for (x = i; x<=j; ++x) a[x] = temp[x];
}
int main() {
int i;
freopen("scmax.in", "r", stdin);
freopen("scmax.out", "w", stdout);
scanf("%d", &n);
for (i=0;i<n;++i) {
scanf("%d", &X[i]);
smallest_tail[i] = -1;
}
smallest_tail[n] = -1;
for (i=0;i<n;++i) S[i]=i;
/*qsort(S, n, sizeof(int), sortme);*/
merges(S, 0, n-1);
for (i=0;i<n;++i) SS[S[i]] = i;
/* printf("S: "); for (i=0;i<n;i++) printf("%d ", S[i]);
printf("\nSS: "); for (i=0;i<n;i++) printf("%d ", SS[i]);
printf("\n");*/
for (i=0;i<n;++i) {
int temp = SS[i] - 1;
int l;
while (temp>=0 && X[S[temp]]==X[i]) temp--;
l = getmax(temp+1);
P[i] = smallest_tail[l];
/*printf("l:%d %d %d %d %d\n", i, X[i], l, P[i], temp);*/
add(SS[i]+1, l + 1);
if (smallest_tail[l+1] == -1 || X[i]<X[smallest_tail[l+1]]) smallest_tail[l+1] = i;
}
printf("%d\n", getmax(n));
backwrite(smallest_tail[getmax(n)]);
printf("\n");
return 0;
}