以下问题可能十分弱智,大佬们轻喷谢谢
我大概对单调栈理解的有问题,tj 里都是构造一个单调递减的栈,从左往右算一遍,但是我觉得这样难道不是只能统计 可以互相看见的人对 中左边的人比右边的人高的情况吗?我自己写的本来是从左往右算一遍再从右往左算一遍(计算 可以互相看见的人对 中右边的人比左边的人高的情况)的,确实错了,但请问为什么可以只统计一遍呢?
我觉得如这篇题解这样做最坏会出现 O(n2) 的情况(相同的数字反复弹出又压入),于是我这样处理了连续的相同数字的情况(可以看到把从右往左算的注释掉了),统计一下连续的数字个数,放入 b 数组,再对 b 数组进行单调栈的做法,但是 WA 20pts,我不理解为什么错了,求大佬指教 Orz:
#include <stdio.h>
#include <stack>
#include <vector>
using namespace std;
const int S = 5e5 + 5;
typedef pair<int, int> P;
int n, a[S], h[S];
P b[S];
long long ans;
stack<int> st;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
h[i] = i;
}
for (int i = 1; i <= n; i++) {
if (a[i] == a[i - 1]) {
h[i] = h[i - 1];
}
}
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (h[i] != h[i - 1]) {
cnt++;
b[cnt].first = a[i];
b[cnt].second = 1;
} else {
b[cnt].second++;
}
}
for (int i = 1; i <= cnt; i++) {
while (!st.empty() && b[st.top()].first < b[i].first) {
ans += (b[st.top()].second * b[i].second);
st.pop();
}
if (!st.empty()) {
ans += b[st.top()].second * b[i].second;
}
st.push(i);
}/*
while (!st.empty()) {
st.pop();
}
for (int i = cnt; i >= 1; i--) {
while (!st.empty() && b[st.top()].first < b[i].first) {
ans += b[st.top()].second;
st.pop();
}
if (!st.empty()) {
ans++;
}
st.push(i);
}*/
printf("%lld", ans);
return 0;
}
球球了