洛谷題單指南-常見最佳化技巧-P2866 [USACO06NOV] Bad Hair Day S

五月江城發表於2024-08-15

原題連結:https://www.luogu.com.cn/problem/P2866

題意解讀:每個牛能看到的右邊比他矮的牛,直到有比他高的擋住為止,因此只用找每個牛右邊第一個比他高的牛的位置即可計算中間比他矮的有多少。

解題思路:

典型的單調棧應用,注意,常規的單調棧可以用來:

1、找每個數左邊第一個比他小的數的位置

2、找每個數左邊第一個比他大的數的位置

但是此題是要找每個牛右邊第一個比他矮的,也就是每個數右邊第一個比他大的位置,只需要從後往前處理(i從n->1),即可轉換為常規的單調棧模型:

第一步:如果棧不空且當前元素大於棧頂元素,則不斷彈棧

第二步:此時如果棧不空,棧頂即第一個比當前元素大的數的位置r=s.top();如果棧空可以設該位置為r=n+1;這樣當前數能看到的牛數量為r-i-1

第三步:將當前數的位置i入棧

100分程式碼:

#include <bits/stdc++.h>
using namespace std;

const int N = 80005;
stack<int> s;
int n;
int a[N];
long long ans;

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];

    for(int i = n; i >= 1; i--)
    {
        while(s.size() && a[i] > a[s.top()]) s.pop();

        //a[i]右邊第一個比a[i]大的數的位置
        int r = s.empty()? n + 1 : s.top();
        ans += r - i - 1;

        s.push(i);
    }

    cout << ans;
    return 0;
}

相關文章