an approach
IntuitionApproachnge[i] -> next strictly greater element
ngee[i] -> next greater than or equal element.
a[k] > a[j] -> this can be achieved by the nge[nge[i]]
a
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->

# Approach
<!-- Describe your approach to solving the problem. -->
nge[i] -> next strictly greater element
ngee[i] -> next greater than or equal element.
1) a[k] > a[j] -> this can be achieved by the nge[nge[i]]
2) a[k] = a[j] -> this can be achieved by the ngee[nge[i]]
3) a[k] < a[j] -> for this one can find the first element in the range [nge[i]+1 ... n-1] which is greater than a[i]
 -> one can find this using a seg tree, by using bin search to find the first index. in the range given above.  

note-> although this is not very efficient this can be optimised.
# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
O(n * log n * log n)

- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
O(n)

# Code
```cpp []
class Solution {
public:
    const int inf = 2e9;
    int t[4 * 100100];
    int a[100100];
    void build(int node, int st, int end) {
        if (st == end) {
            t[node] = a[st];
            return;
        }

        int mid = (st + end) >> 1;
        build(2 * node, st, mid);
        build(2 * node + 1, mid + 1, end);

        t[node] = max(t[2 * node], t[2 * node + 1]);
    }


    int query(int node, int st, int end, int l, int r) {
        if (l > end || r < st)return -inf;
        if (st >= l && end <= r)return t[node];
        int mid = (st + end) >> 1;
        return max(query(2 * node, st, mid, l, r), query(2 * node + 1, mid + 1, end, l, r));
    }
    vector<int> secondGreaterElement(vector<int>& nums) {
        int n = nums.size();

        for (int i = 0; i < n; ++i)a[i] = nums[i];
        build(1, 0, n - 1);
        vector<int>nge(n, n), ngee(n, n);
        stack<int>s;
        for (int i = n - 1; i >= 0; --i) {
            while (!s.empty() && a[s.top()] <= a[i]) {
                s.pop();
            }
            if (size(s)) nge[i] = s.top();
            s.push(i);
        }

        while (!s.empty())s.pop();
        for (int i = n - 1; i >= 0; --i) {
            while (!s.empty() && a[s.top()] < a[i]) {
                s.pop();
            }
            if (size(s)) ngee[i] = s.top();
            s.push(i);
        }

        vector<int>ans(n);
        for (int i = 0; i < n; ++i) {
            int x = nge[i];
            if (x < n) {
                ans[i] = ngee[x];
                int lo = x + 1; int hi = n - 1;
                int j = n;
                while (lo <= hi) {
                    int mid = (lo + hi) >> 1;
                    int y = query(1, 0, n - 1, x + 1, mid);
                    if (y > a[i]) {
                        j = mid;
                        hi = mid - 1;
                    }
                    else {
                        lo = mid + 1;
                    }
                }
                ans[i] = min(ans[i], j);
                if (ans[i] < n)ans[i] = a[ans[i]];
                else ans[i] = -1;
            }
            else ans[i] = -1;
        }
        return ans;
    }
};
```
['C++']