abc372D Buildings

chenfy27發表於2024-10-07

N幢樓排成一行,第i號樓的高度為H[i]。對於每幢樓,右邊有多少幢樓滿足兩樓之間的樓高都不超過右側樓高?
1<=N<=2E5, 1<=H[i]<=N, H[i]!=Hj

分析:單調棧求出各幢樓左邊最近的比它高的樓,對於j號樓,假設它左邊最近的比它高的樓號為i,那麼j對區間[i,j-1]中每個下標都有1的貢獻,可以用差分來維護。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
    int N;
    std::cin >> N;
    std::vector<int> H(N + 2);
    for (int i = 1; i <= N; i++) {
        std::cin >> H[i];
    }

    std::vector<int> L(N + 2), s;
    for (int i = 1; i <= N; i++) {
        while (!s.empty() && H[s.back()] <= H[i]) {
            s.pop_back();
        }
        L[i] = s.empty() ? 0 : s.back();
        s.push_back(i);
    }

    std::vector<int> A(N + 2);
    for (int i = 1; i <= N; i++) {
		A[L[i]] += 1;
		A[i] -= 1;
    }
    std::partial_sum(A.begin(), A.end(), A.begin());
    for (int i = 1; i <= N; i++) {
    	std::cout << A[i] << " \n"[i == N];
    }
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}