IOI2018 meetings


萌新瞎想了很直接的 \(\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})\) 中。

那么:

  1. \([l,S_x)\) 的貢獻均為 \(S_x\)
  2. \([S_{x+1},r)\) 中一個元素的貢獻只和該元素在棧中哪兩個元素之間有關。
  3. 由於 \(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\) 就過了。

\(n^2\) 過百萬,暴力碾標算!

觀察我們的暴力是怎么完成的:其實是求了樹上一條鏈的 \(\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)\),不過我懶就沒寫

aclink

感覺這種思路也是可以再優化的,畢竟鏈上的元素是有單調性的。

祝大家學習愉快!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM