--- lang: zh-Hant-TW dir: ltr description: Monotonic queue(臺灣正體:單調佇列;大陆简体:单调队列) --- # 單調佇列 ## 單調棧(monotonic stack) 1. 建立一個stack,存pair:**{值, 位置}** 2. 從左到右,每次pop stack直到最高元素比自己大(目前位置減掉頂端,就是從當下往後數第一個比自己大的位置) 3. 原因: * 如果目前值比stack的頂還大,那目前的值也一定比小於stack頂端的值還大(也就是前面步驟所pop掉的)。但卻不知道會不會大於stack頂端的值還大,所以要pop直到比自己還大。 * $O(2n) = O(n)$ 一個點最多走兩次 * 最佳化:二分搜($O(n+logn)$) ```cpp= int main() { ios_base::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vci nums(n); rep(0, n) cin >> nums[i]; stack<pair<int,int>> st; LL res = 0; rep(0, n) { while (!st.empty() && st.top().first<=nums[i]) { st.pop(); } res += st.empty() ? i + 1 : i - st.top().S; st.push({nums[i], i}); } cout << res << NL; } ``` <https://judge.tcirc.tw/ShowProblem?problemid=d028> ## 單調佇列(monotonic queue) * 跟單調棧一樣,但是多了要維持邊界 * 用deque,右邊做單調性維護,左邊做邊界維護 * $O(n)$
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.