题目地址:FJSDFZOJ 1308 音乐会的等待
对于l和r,如果[l, r]内没有大于min(l,r)的数,则这两个数可以互相看见。
求能互相看见的对数
标程对题意的理解比较奇怪。
特别要注意以下三个case:
7
2 4 1 2 2 5 1
8
2 4 1 2 2 5 5 1
9
2 4 1 2 2 2 5 5 1
题解:
[SMOJ2116]诺诺的队列
音乐会的等待(诺诺的队列)
系统学习单调栈和单调队列戳:单调队列和单调栈详解
https://endlesslethe.com/monotone-queue-and-stack-tutorial.html
AC代码:
#include <bits/stdc++.h>
using namespace::std;
typedef long long ll;
const int MAXN = 500000+50;
struct M {
ll x; ll len;
} x[MAXN];
stack <M> ms;
ll cnt, n;
int main() {
ios_base::sync_with_stdio(0);cin.tie(0);
#ifdef LOCAL
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif
while (scanf("%d", &n) == 1) {
cnt = 0;
while (!ms.empty()) ms.pop();
for (ll i = 0; i < n; i++) {
scanf("%d", &x[i].x);
x[i].len = 1;
M tmp = x[i];
while (!ms.empty() && ms.top().x < x[i].x) {
cnt += ms.top().len;
ms.pop();
}
if (!ms.empty() && ms.top().x == x[i].x) {
cnt += ms.top().len;
tmp.len = ms.top().len + 1;
ms.pop();
}
if (!ms.empty()) cnt++;
ms.push(tmp);
}
printf("%lld\n", cnt);
}
return 0;
}