紧接上文:今天给大家看看另一个我觉得我可以做出来但是没做出来的题。
这题乍一看是不是很简单,别着急,时间复杂度限制为o(n),也就是说朴素方法不能过题~
所以要使用单调栈(就是很单调的栈[doge]),这里的“单调”跟单调函数的单调是一个意思。
所以单调栈是从栈顶到栈底严格递增或递减的栈。
关于栈的基本使用,我就不赘述了,注释很多,大家请看吧
#include<iostream>
#include<stack>
using namespace std;
int main()
{
stack<int>s;
int n = 0;
scanf("%d", &n);
long long ans = 0;
int h = 0;
for (int i = 0; i < n; i++)
{ //这样遍历可能会被误解为是“向左看”,其实不是。假设我们第一个数10,入栈,后面的3比10小,ans就变成了1,则计算的不是3号往后看的人数,而是10号。
scanf("%d", &h);
while (!s.empty() && s.top() <= h) //刚开始是空的,所以第一个元素可以入栈
//这样遍历可能会被误解为是“向左看”,其实不是。假设我们第一个数10,入栈,后面的3比10小,ans就变成了1,则计算的不是3号往后看的人数,而是10号。
s.pop(); //如果栈顶的元素比输入的小,就把它剔除掉,直到找到小于现在的为止
ans += s.size();
s.push(h); //因为自己看不到自己,所以新人入栈要在计算的后面
}
printf("%lld", ans);
return 0;
}
希望和诸君共勉。