1. 程式人生 > 實用技巧 >「題解」POJ3250 Bad Hair Day

「題解」POJ3250 Bad Hair Day

題目

3250 Bad Hair Day

簡化題意

每一頭牛能看到在他後面第一頭身高大於等於它的牛前面所有的牛。計算每頭牛能看到的牛的數量和。

思路

單調棧,懸線法。

對每一個數找最右邊第一個大於等於的它的數。

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 << '\n';
    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 << '\n';
    return 0;
}