|
@@ -1,34 +1,33 @@
|
|
|
// Given a list of numbers of length n, this routine extracts a
|
|
|
// longest increasing subsequence.
|
|
|
-//
|
|
|
// Running time: O(n log n)
|
|
|
-//
|
|
|
-// INPUT: a vector of integers
|
|
|
-// OUTPUT: a vector containing the longest increasing subsequence
|
|
|
-// #define STRICTLY_INCREASNG // buggué, quand on retrouve la suite ?
|
|
|
-VI LongestIncreasingSubsequence(VI v) {
|
|
|
- VPII best;
|
|
|
- VI dad(v.size(), -1);
|
|
|
- for (int i = 0; i < v.size(); i++) {
|
|
|
-#ifdef STRICTLY_INCREASNG
|
|
|
- PII item = make_pair(v[i], 0);
|
|
|
- VPII::iterator it = lower_bound(best.begin(), best.end(), item);
|
|
|
- item.second = i;
|
|
|
-#else
|
|
|
- PII item = make_pair(v[i], i);
|
|
|
- VPII::iterator it = upper_bound(best.begin(), best.end(), item);
|
|
|
-#endif
|
|
|
- if (it == best.end()) {
|
|
|
- dad[i] = (best.size() == 0 ? -1 : best.back().second);
|
|
|
- best.push_back(item);
|
|
|
- } else {
|
|
|
- dad[i] = dad[it->second];
|
|
|
- *it = item;
|
|
|
- }
|
|
|
- }
|
|
|
- VI ret;
|
|
|
- for (int i = best.back().second; i >= 0; i = dad[i])
|
|
|
- ret.push_back(v[i]);
|
|
|
- reverse(ret.begin(), ret.end());
|
|
|
- return ret;
|
|
|
-}
|
|
|
+int A[MAX_N], indice[MAX_N], back[MAX_N];
|
|
|
+VI lis(VI values, bool strict) {
|
|
|
+ int N = values.size();
|
|
|
+ int k = 0;
|
|
|
+ fill_n(back, N, -1);
|
|
|
+ for(int i = 0; i < N ; i++) {
|
|
|
+ int j;
|
|
|
+ if(strict)
|
|
|
+ j = lower_bound(A, A + k, values[i]) - A;
|
|
|
+ else
|
|
|
+ j = upper_bound(A, A + k, values[i]) - A;
|
|
|
+ if(j == k) {
|
|
|
+ A[k] = values[i];
|
|
|
+ indice[k] = i;
|
|
|
+ ++k;
|
|
|
+ } else if(values[i] < A[j]) {
|
|
|
+ A[j] = values[i];
|
|
|
+ indice[j] = i;
|
|
|
+ }
|
|
|
+ if(i && j && j-1 < k)
|
|
|
+ back[i] = indice[j-1];
|
|
|
+ }
|
|
|
+ VI longest(k);
|
|
|
+ int cur = indice[k-1];
|
|
|
+ for(int i = longest.size()-1; i >= 0; i--) {
|
|
|
+ longest[i] = values[cur];
|
|
|
+ cur = back[cur];
|
|
|
+ }
|
|
|
+ return longest;
|
|
|
+}
|