题目
简化题意
每一头牛能看到在他后面第一头身高大于等于它的牛前面所有的牛。计算每头牛能看到的牛的数量和。
思路
单调栈,悬线法。
对每一个数找最右边第一个大于等于的它的数。
Code
悬线法:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 80001
typedef long long ll;
ll ans;
int n, a[M], r[M];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
r[i] = i;
}
for (int i = n; i >= 1; --i) {
while (r[i] < n && a[i] > a[r[i] + 1]) r[i] = r[r[i] + 1];
}
for (int i = 1; i <= n; ++i) ans += r[i] - i;
std::cout << ans << '
';
return 0;
}
单调栈:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 80001
#define int long long
int n, top, s[M], a[M];
signed main() {
scanf("%lld", &n);
int ans = 0;
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
while (top && a[s[top]] <= a[i]) {
ans += i - s[top] - 1;
--top;
}
s[++top] = i;
}
while (top) {
ans += n - s[top];
--top;
}
std::cout << ans << '
';
return 0;
}