【Luogu P2866】[USACO06NOV]Bad Hair Day S
[USACO06NOV]Bad Hair Day S
洛谷题面
题目大意:
给定有 \(n\) 个数的数组 \(a_i\),找到在 \(i\) 之后的第一个大于 \(a_i\) 的数 \(a_j\),那么 \(a_i\) 能造成 \(j-i\) 贡献。求总贡献。
思路:
倒着跑单调栈。
代码:
const int N = 8e4 + 10;
inline ll Read() {
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
int n;
ll a[N];
ll q[N], t, ans;
int main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
n = Read ();
for (int i = 1; i <= n; i++) a[i] = Read();
for (int i = n; i; i--) {
for (; t && a[q[t]] < a[i]; t--);
if (!t) ans += n - i;
else ans += q[t] - i - 1;
q[++t] = i;
}
printf ("%lld\n", ans);
return 0;
}