「題解」POJ3250 Bad Hair Day
阿新 • • 發佈:2020-09-11
題目
簡化題意
每一頭牛能看到在他後面第一頭身高大於等於它的牛前面所有的牛。計算每頭牛能看到的牛的數量和。
思路
單調棧,懸線法。
對每一個數找最右邊第一個大於等於的它的數。
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; }