11.3 模擬賽

summ1t發表於2024-11-03

T1:

原題連結

orz 盜版說的道理

T2:

原題連結

不難發現,設最終每段黑白比值為 \(C\),則 \(\frac{\sum W}{\sum B}=C\),我們可以直接算出每段的黑白格子比值為多少。

接下來考慮如何讓劃分割槽間最多:

  • 結論: 一定是恰好滿足 \(\frac{W}{B}=C\) 的最小的區間。

  • 證明:\([1,x],[1,y]\) 區間均滿足條件,且 \(x<y\),發現 \(\frac{W_{1,x}}{B_{1,x}}=\frac{W_{1,y}}{B_{1,y}}=\frac{W_{x+1,y}}{B_{x+1,y}}\),所以選 \([1,y]\) 不如選 \([1,x],[x+1,y]\),能產生更多貢獻。

接下來模擬上述貪心過程即可。

T3:

原題連結

棋盤上放置方案問題,很容易想到動態規劃求解,觀察資料範圍,無法狀態壓縮。

但再觀察,發現某一列上最多隻能放兩個棋子,某一行也同理,所以我們可以這樣設計狀態:令 \(f_{i,j,k}\) 表示前 \(i\) 行,有 \(j\) 列放了一個棋子,\(k\) 列放了兩個棋子的方案數。

轉移時列舉第 \(i\) 行放了多少棋子:

  • 不放棋子,直接從上一行狀態轉移來:\(f_{i,j,k}=f_{i-1,j,k}\)

  • 放一枚棋子,它可以放到之前沒有棋子的和有一枚棋子的列:\(f_{i,j,k}=\begin{cases}f_{i-1,j-1,k}\times (m-(j-1)-k)\\f_{i-1,j+1,k-1}\times (j+1) \end{cases}\)

  • 放兩枚棋子,可以都放到沒棋子的列,都放到放一枚棋子的列,以及分別放沒棋子和有一枚棋子的列。
    轉移方程為:\(f_{i,j,k}=\begin{cases}f_{i-1,j-2,k}\times C_{m-(j-2)-k}^{2} \\f_{i-1,j+2,k-2}\times C_{j+2}^{2}\\ f_{i-1,j,k-1}\times j\times (m-j-(k-1)) \end{cases}\)

最後答案為 \(\sum_{j=0}^{m}\sum_{k=0}^{m}f_{n,j,k}\)

T4:

原題連結

可以暴力列舉 \(a,b\),然後 \(c\in [2b-a,n]\),找區間最大值即可。

對於我們選擇的 \(a,b\) 間,若能在 \((a,b)\) 中找到某個下標 \(i\),滿足 \(h_i\ge h_a\)\(h_i\ge h_b\),那麼選擇 \(i\) 是更優的。

理由很簡單,無論是從 \(a\to i\) 還是從 \(b\to i\),都會擴大 \(c\) 的選擇區間,同時還能增大你的 \(h_a+h_b\)

所以我們只找滿足以下條件的 \(a,b\)

  • \([a,b]\) 中最大值 \(< \min\{h_a,h_b\}\)

這不就是找到一個數,它左右兩邊的最近的大於等於它的數嗎。直接單調棧求出,並且這樣的數對是 \(O(n)\) 級別的。

然後我們把詢問離線下來,從大到小列舉左端點進行掃描線,對於新的左端點 \(i\),先把預處理來的數對 \((a,b),a=i\) 對答案進行更新。

如何維護答案?考慮線段樹,設 \(B_i\) 表示如果選 \(i\) 作為 \(c\),它左邊的最大的 \(h_a+h_b\),對於新來的數對 \((a,b)\),將 \([2b-a,n]\) 中的 \(B_i\)\(h_a+h_b\)\(\max\),這個用線段樹很好維護。

對於左端點為 \(i\) 的所有詢問,查詢區間 \([i+2,r]\)\(B_i+h_i\) 的最大值。

所以線段樹維護 \(h_i,B_i+h_i\) 的最大值,支援與某個數取 \(\max\) 操作,這道題就做完了。

時間複雜度 \(O((n+q)logn)\)