萌新瞎想了很直接的 \(\Theta(nq)\)(在 \(\rm Luogu\) 上過了) 和一個 \(\Theta(n \log n +q \log^3 n)\) (在 \(\rm UOJ\) 上過了)的做法,就寫篇題解吧。
在 \(\rm UOJ\) 過了的做法在 \(\rm Luogu\) 上過不去應該是因為洛谷空間開小了。
題意
給定長度為 \(n\) 的序列 \(h\),\(q\) 次詢問,每次給定區間 \([l,r]\),你要在 \([l,r]\) 中選出一個位置 \(x\) 舉行會議,使得 \(\sum\limits_{l \le i \le r} \max_{j \in [\min(i,x),\max(i,x)]} h_j\) 最小。
數據范圍:\(1 \le n, q \le 7.5 \times 10^5\),\(1 \le h_i \le 10^9\)。
題解
首先考慮暴力怎么做:每次找到區間中的 \(\rm max\),然后枚舉是把會議丟 \(\rm max\) 的左邊還是丟右邊即可,問題就被分成了兩半。
考慮優化,先找到整個區間的最大值,然后把問題切成兩半。不妨考慮左邊那一半怎么做。
考慮先建出左邊那半的單調棧。設棧中元素為 \(S_1,S_2,S_3,...,S_k\)。
其中 \(h_{S_i} \le h_{S_{i+1}}\),\(S_1 = l\),\(S_k = r\)。
枚舉我們選擇的會議處於棧中哪兩個元素之間。假設設在 \([S_x,S_{x+1})\) 中。
那么:
- \([l,S_x)\) 的貢獻均為 \(S_x\)。
- \([S_{x+1},r)\) 中一個元素的貢獻只和該元素在棧中哪兩個元素之間有關。
- 由於 \(x+1\) 是 \(x\) 后面第一個值 \(> h_x\) 的元素,因此 \([S_x,S_{x+1})\) 中元素的貢獻可以預處理(找到 \((S_x,S_{x+1})\) 中的最大值,然后可以遞歸成形式相同的子問題)。
於是我們就會 \(\Theta(nq)\) 了。
直接寫是過不去的。我們預處理出 \(fa_i\) 為 \(i\) 后第一個 \(> h_i\) 的元素。
然后從 \(l\) 開始暴力跳 \(fa\) 跳到 \(r\) 就過了。
觀察我們的暴力是怎么完成的:其實是求了樹上一條鏈的 \(\max(k_ix+b_i)\)。
於是可以樹剖,轉化為序列上區間 \(\max(k_ix+b_i)\)。建顆線段樹,每個線段樹上的節點 \([L,R]\) 維護一顆李超樹即可。
為了優化復雜度,\([L,R]\) 上的李超樹可以用 \([L,mid]\) 和 \((mid+1,R]\) 的李超樹合並。
其實可以用 XJOI4182 的套路優化到 \(\Theta(n \log n + q \log^2 n)\),不過我懶就沒寫。
感覺這種思路也是可以再優化的,畢竟鏈上的元素是有單調性的。
祝大家學習愉快!