/* * Longest non-decreasing subsequence */ using Nemerle.IO; public class NondecreasingSubsequence { [Record] class node { public mutable best : int; public mutable bestid : int; } static find_longest (seq : array [int]) : int * list [int] { def close2pow (n, pow) { if (n == 0) pow else close2pow (n / 2, pow * 2) }; def n = seq.Length; def pow = close2pow (n, 1); def tab = array (2 * pow + 1); for (mutable i = 2 * pow; i >= 0; i = i - 1) tab[i] = node(0,-1); def insert (dest : int, ex : int, pos : int, bestl : int, bestlid : int) { if (pos >= pow) { tab[pos].best = bestl + 1; tab[pos].bestid = bestlid; } else { def dir = if (dest >= (pos * 2 + 1) * ex / 2) 1 else 0; def child = pos * 2 + dir; def (nb, nbid) = if (bestl < tab[pos * 2].best && dir == 1) if (pos * 2 >= pow) (tab[pos * 2].best, pos * 2 - pow) else (tab[pos * 2].best, tab[pos * 2].bestid) else (bestl, bestlid); insert (dest, ex / 2, child, nb, nbid); when (tab[pos].best < tab[child].best) { tab[pos].best = tab[child].best; if (child >= pow) tab[pos].bestid = child - pow else tab[pos].bestid = tab[child].bestid; } } }; def reconstruct (i : int, next : int, acc : list [int]) { if ( i >= pow ) if ( i - pow == next ) reconstruct (i - 1, tab[i].bestid, next :: acc) else reconstruct (i - 1, next, acc) else acc }; for (mutable i = 0; i < n; i = i + 1) insert (seq[i] + pow, pow, 1, 0, -1); (tab[1].best, reconstruct (n + pow - 1, tab[1].bestid, [])) } public static Main () : void { def sequence = array [4, 0, 2, 6, 1, 3, 5]; def (len, subs) = find_longest (sequence); printf ("%d\n", len); foreach (x in subs) printf ("%d ", x); printf ("\n"); } } /* BEGIN-OUTPUT 4 0 1 3 5 END-OUTPUT */