模版

//以下所有将b[i]=q.top().second改为b[i]=q.top().first 即可得到元素的值而不是坐标。
//n为数组规模,默认下标从1开始
//数组a为原数组
//数组b为查找到的坐标(元素值)
void findRMin(int n,int a[],int b[])   //寻找右边第一个比自己小的元素的坐标
{
    stack<pair<int,int>> q;
    for (int i=n;i>=1;i--)
    {
        while (!q.empty()&&a[i]<=q.top().first)
            q.pop();
        if (q.empty()) b[i]=0;
        else b[i]=q.top().second;
        q.push(make_pair(a[i],i));
    }
}

void findLMin(int n,int a[],int b[])   //寻找左边第一个比自己小的元素的坐标
{
    stack<pair<int,int>> q;
    for (int i=1;i<=n;i++)
    {
        while (!q.empty()&&a[i]<=q.top().first)
            q.pop();
        if (q.empty()) b[i]=0;
        else b[i]=q.top().second;
        q.push(make_pair(a[i],i));
    }
}

void findRMax(int n,int a[],int b[])   //寻找右边第一个比自己大的元素的坐标
{
    stack<pair<int,int>> q;
    for (int i=n;i>=1;i--)
    {
        while (!q.empty()&&a[i]>=q.top().first)
            q.pop();
        if (q.empty()) b[i]=0;
        else b[i]=q.top().second;
        q.push(make_pair(a[i],i));
    }
}

void findLMax(int n,int a[],int b[])   //寻找左边第一个比自己大的元素的坐标
{
    stack<pair<int,int>> q;
    for (int i=1;i<=n;i++)
    {
        while (!q.empty()&&a[i]>=q.top().first)
            q.pop();
        if (q.empty()) b[i]=0;
        else b[i]=q.top().second;
        q.push(make_pair(a[i],i));
    }
}

解释

以寻找右边第一个比自己小的元素的坐标为例,从最后一个元素开始从右往左遍历,栈q中按照从顶到底降序存储。
第一个while循环会弹出栈中所有大于当前元素a[i]的元素,直到找到比自己还小的元素,这使得栈中的所有元素都比a[i]小。
被弹出元素因为其大于当前元素a[i],所以对于a[i]左边的元素来说,被弹出元素不可能为第一个小于的元素,所以被弹出。
随后根据栈中是否有元素来判断右边是否有元素小于它,如果为空则没有,不为空则栈顶端的元素是第一个小于它的元素。
随后将元素a[i]和坐标i压入栈中。


循之际,如星夜般的幻想。