单调栈模板(单调栈)
测试链接:https://www.nowcoder.com/practice/2a2c00e7a88a498693568cef63a4b7bb
思路
先用数组创建一个栈,但数组严格单调上升时候直接入栈,当出现下一个数小于等于的情况时候,出栈更新答案,第一遍遍历数组后,单调栈还存在一些数,接下来将单调栈的数字依次弹出,单调栈的顶部的右边答案显然一定为-1,只需要考虑左边界问题,当单调栈还不为空时候,左边第一个最小值就是压栈的数字,当栈内只剩下一个数字时候,那么这个数字的左右答案就均为-1,而最后从后往前处理相同值情况,可以保证只需要一次传递就可以更新不同的答案,如果从前往后可能会出现需要更新多次的情况。
题解
#include <bits/stdc++.h>
#include <unistd.h>
using namespace std;
const int N=1e6+10;
int ans[N][2];
int stk[N];
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
int r=0;
for(int i=0;i<n;i++)
{
while(r>0&&a[stk[r-1]]>=a[i])
{
int cur = stk[--r];
ans[cur][0]= r>0?stk[r-1]:-1;
ans[cur][1] = i;
}
stk[r++]=i;
}
while(r>0)
{
int cur = stk[--r];
ans[cur][1]=-1;
ans[cur][0]=r>0?stk[r-1]:-1;
}
for(int i=n-2;i>=0;i--)
{
if(ans[i][1]!=-1&&a[i]==a[ans[i][1]])ans[i][1]=ans[ans[i][1]][1];
}
for(int i=0;i<n;i++)cout<<ans[i][0]<<' '<<ans[i][1]<<endl;
return 0;
}
洛谷模板
测试链接:https://www.luogu.com.cn/record/222806264
#include <bits/stdc++.h>
using namespace std;
const int N=3e6+10;
typedef long long ll;
int t,n;
int stk[N];
int ans[N];
ll a[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)cin>>a[i];
int r=1;
for(int i=1;i<=n;i++)
{
while(r>1&&a[i]>a[stk[r-1]])
{
int cur = stk[--r];
ans[cur] = i;
}
stk[r++]=i;
}
for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
cout<<endl;
return 0;
}

浙公网安备 33010602011771号