单调栈的经典应用
单调栈的经典应用是在O(n)的时间复杂度内求出所有的L[i]和R[i]。
L[i]表示从i向左遍历第一个比a[i]小/大的值的下标。
R[i]表示从i向右遍历第一个比a[i]小/大的值的下标。
如果是小的话,维护一个单调递增栈;否则,维护单调递减栈。
代码
const int maxn=1e5+7;
int h[maxn],n;
int L[maxn];//L[i]表示从i向左遍历,第一个比h[i]小的值的下标
void getL()
{
stack<int> S;
for(int i=1;i<=n;i++)//向右遍历维护一个单调递增栈
{
while(S.size() && h[S.top()]>=h[i]) S.pop();
L[i]=S.empty()?0:S.top();
// printf("%d %d\n",i,L[i]);
S.push(i);
}
}
int R[maxn];//R[i]表示从i向右遍历,第一个比h[i]小的值的下标
void getR()
{
stack<int> S;
for(int i=n;i>=1;i--)//向左遍历维护一个单调递增栈
{
while(S.size() && h[S.top()]>=h[i]) S.pop();
R[i]=S.empty()?n+1:S.top();
// printf("%d %d\n",i,R[i]);
S.push(i);
}
}