Given a permutation from 1 to N of size N. Find the length of the longest subsequence having the property that the first and last element is greater than all the other subsequence elements.

**Examples:**

Input :N = 6

4 2 6 5 3 1

Output :3

The subsequence that has the longest size is [4, 2, 3] or [4, 2, 6] or [4, 2, 5]. No other subsequence holds the above property with first and last element greater than all remaining subsequence elements.

Input :N = 5

5 4 1 2 3

Output :4

The longest subsequence is [5, 1, 2, 3] or [4, 1, 2, 3]. With 5 and 3 greater than all other subsequence elements i.e 1 and 2.

**Approach:**

Idea is to use Fenwick tree data structure.Start iterating from the highest value in the permutation to lowest one. For each iteration, move left or a right pointer to the current element only if the left pointer can be moved to more left and right pointer to more right.

If left index is L and right index is R then there are elements from [L+1, R-1] in between. For this particular iteration i, count the number of elements that are lesser than min(arr[L], arr[R]) using the fenwick tree.

Store each query of type {left+1, right-1, val, index}, where left and right are current left and right pointers and val is the min of arr[L] and arr[R] and idx is the index of that particular query.

- Sort the array in ascending order.
- Sort the queries according to val i.e min(arr[L], arr[R] ) in ascending order, initialize Fenwick array as 0.
- Start from the first query and traverse the array until the value in the array is less than equal to val. For each such element update the Fenwick tree with value equal to 1.
- Query the Fenwick array in the range l to r.
- Print maximum of all the query results .

Below is the implementation of the above approach:

`// C++ implementation of the above approach ` ` ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `struct` `Query { ` ` ` ` ` `int` `l, r, x, index; ` `}; ` ` ` `struct` `Arrays { ` ` ` ` ` `int` `val, index; ` `}; ` ` ` `// Comparison functions ` `bool` `cmp1(Query q1, Query q2) ` `{ ` ` ` `return` `q1.x < q2.x; ` `} ` ` ` `bool` `cmp2(Arrays x, Arrays y) ` `{ ` ` ` `return` `x.val < y.val; ` `} ` ` ` `// Function to update the value in Fenwick tree ` `void` `update(` `int` `* Fenwick, ` `int` `index, ` `int` `val, ` `int` `n) ` `{ ` ` ` `while` `(index <= n) { ` ` ` ` ` `Fenwick[index] += val; ` ` ` `index += index & (-index); ` ` ` `} ` `} ` ` ` `// Function to return the query result ` `int` `query(` `int` `* Fenwick, ` `int` `index, ` `int` `n) ` `{ ` ` ` `int` `sum = 0; ` ` ` ` ` `while` `(index > 0) { ` ` ` ` ` `sum = sum + Fenwick[index]; ` ` ` `index -= index & (-index); ` ` ` `} ` ` ` ` ` `return` `sum; ` `} ` ` ` `// Function to return the length of subsequence ` `int` `maxLength(` `int` `n, vector<` `int` `>& v) ` `{ ` ` ` `int` `where[n + 2]; ` ` ` ` ` `memset` `(where, 0, ` `sizeof` `where); ` ` ` ` ` `Arrays arr[n]; ` ` ` ` ` `// Store the value in struct Array ` ` ` `for` `(` `int` `i = 1; i <= n; ++i) { ` ` ` ` ` `v[i - 1] = v[i - 1] - 1; ` ` ` ` ` `int` `x = v[i - 1]; ` ` ` ` ` `where[x] = i - 1; ` ` ` `arr[i - 1].val = x; ` ` ` `arr[i - 1].index = i - 1; ` ` ` `} ` ` ` ` ` `// If less than 2 elements are ` ` ` `// present return that element. ` ` ` `if` `(n <= 2) { ` ` ` ` ` `cout << n << endl; ` ` ` ` ` `return` `0; ` ` ` `} ` ` ` ` ` `// Set the left and right pointers to extreme ` ` ` `int` `left = n, right = 0, mx = 0; ` ` ` ` ` `Query queries[4 * n]; ` ` ` ` ` `int` `j = 0; ` ` ` `for` `(` `int` `i = n - 1; i >= 0; --i) { ` ` ` ` ` `// Calculate left and right pointer index. ` ` ` `left = min(left, where[i]); ` ` ` `right = max(right, where[i]); ` ` ` ` ` `int` `diff = right - left; ` ` ` ` ` `if` `(diff == 0 || diff == 1) { ` ` ` `continue` `; ` ` ` `} ` ` ` ` ` `int` `val1 = v[left]; ` ` ` `int` `val2 = v[right]; ` ` ` `int` `minn = min(val1, val2); ` ` ` ` ` `// Store the queries from [L+1, R-1]. ` ` ` `queries[j].l = left + 1; ` ` ` `queries[j].r = right - 1; ` ` ` `queries[j].x = minn; ` ` ` `queries[j].index = j; ` ` ` ` ` `++j; ` ` ` `} ` ` ` ` ` `int` `Fenwick[n + 1]; ` ` ` ` ` `memset` `(Fenwick, 0, ` `sizeof` `Fenwick); ` ` ` ` ` `int` `q = j - 1; ` ` ` ` ` `// Sort array and queries for fenwick updates ` ` ` `sort(arr, arr + n + 1, cmp2); ` ` ` `sort(queries, queries + q + 1, cmp1); ` ` ` ` ` `int` `curr = 0; ` ` ` `int` `ans[q]; ` ` ` `memset` `(ans, 0, ` `sizeof` `ans); ` ` ` ` ` `// For each query calculate maxx for ` ` ` `// the answer and store it in ans array. ` ` ` `for` `(` `int` `i = 0; i <= q; ++i) { ` ` ` ` ` `while` `(arr[curr].val <= queries[i].x and curr < n) { ` ` ` ` ` `update(Fenwick, arr[curr].index + 1, 1, n); ` ` ` `curr++; ` ` ` `} ` ` ` ` ` `ans[queries[i].index] = ` ` ` `query(Fenwick, queries[i].r + 1, n) ` ` ` `- query(Fenwick, queries[i].l, n); ` ` ` `} ` ` ` ` ` `for` `(` `int` `i = 0; i <= q; ++i) { ` ` ` `mx = max(mx, ans[i]); ` ` ` `} ` ` ` ` ` `// Mx will be mx + 2 as while calculating ` ` ` `// mx, we excluded element ` ` ` `// at index left and right ` ` ` `mx = mx + 2; ` ` ` `return` `mx; ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` `int` `n = 6; ` ` ` `vector<` `int` `> v = { 4, 2, 6, 5, 3, 1 }; ` ` ` ` ` `cout << maxLength(n, v) << endl; ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

3

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Longest subsequence such that every element in the subsequence is formed by multiplying previous element with a prime
- Length of longest subarray in which elements greater than K are more than elements not greater than K
- Longest subsequence having greater corner values
- Longest Subarray with first element greater than or equal to Last element
- Longest Subsequence where index of next element is arr[arr[i] + i]
- Longest Subsequence with at least one common digit in every element
- Length of Smallest Subsequence such that sum of elements is greater than equal to K
- Longest subarray in which absolute difference between any two element is not greater than X
- Longest subarray in which all elements are greater than K
- Longest alternating subsequence which has maximum sum of elements
- Longest subsequence such that adjacent elements have at least one common digit
- Maximize sum of all elements which are not a part of the Longest Increasing Subsequence
- Length of the longest subsequence such that xor of adjacent elements is non-decreasing
- Length of longest subsequence in an Array having all elements as Nude Numbers
- Maximum difference between frequency of two elements such that element having greater frequency is also greater
- Count elements whose sum with K is greater than max element
- Find the element before which all the elements are smaller than it, and after which all are greater
- Elements greater than the previous and next element in an Array
- Count of greater elements for each element in the Array
- Sum of elements in an array with frequencies greater than or equal to that element

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.