题意
传送门 POJ 2350
题解
非严格单调栈
若考虑每一头牛可以看到的数量,则需要求解满足 h [ j ] > = h [ i ] h[j]>=h[i] h[j]>=h[i] 的最大的 j j j,逆向遍历,非严格单调栈求解。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 80005
typedef long long ll;
int n, h[maxn], st[maxn];
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", h + i);
}
ll res = 0;
int t = 0;
for (int i = n - 1; i >= 0; i--)
{
while (t > 0 && h[st[t - 1]] < h[i])
--t;
res += (t ? st[t - 1] : n) - i - 1, st[t++] = i;
}
printf("%lld\n", res);
return 0;
}
严格单调栈
若考虑每一头牛被其他牛看到的次数,则需要求解满足 h [ j ] > h [ i ] h[j]>h[i] h[j]>h[i] 的最小的 j j j,正向遍历,严格单调栈求解。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 80005
typedef long long ll;
int n, h[maxn], st[maxn];
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", h + i);
}
ll res = 0;
int t = 0;
for (int i = 0; i < n; i++)
{
while (t > 0 && h[st[t - 1]] <= h[i])
--t;
res += t, st[t++] = i;
}
printf("%lld\n", res);
return 0;
}