CF1802 題解

snowycat1234發表於2024-10-30

CF1802 題解

A likes

最大值一定是一個字首全部關注, 一個字尾全部取關.

最小值一定是一個字首關注完立刻取關, 後面全部是關注.

模擬即可.

B Settlement of Guinea Pigs

那些未確定性別的只能每個單獨佔一個籠子, 其他的需要我們去分配.

如果有 \(m\) 個松鼠被確定性別了, 其中 \(k\) 個是男性, 那麼需要 \(\lceil\frac{k}{2}\rceil + \lceil\frac{n-k}{2}\rceil\) 個籠子, 對 \(m,k\) 奇偶分討即取最大值得答案.

C The Very Beautiful Blanket

由題意得, \(a_{i,j}\oplus a_{i+1,j}\oplus a_{i,j+1}\oplus a_{i+1,j+1} = f_{i\bmod 2,j\bmod 2}\) 只有 \(4\) 種取值, 觀察樣例發現有數字重複的機率不大, (並且大機率與位運算有關 ps: 正解確實是位運算). 這樣的話, 我們只要構造出第一行和第一列的 \(a\) , 並且決策出 \(f\) 的四個值就可以唯一確定整個 \(a\) 矩陣.

如何決策呢? 發現重複的機率並不高, 直接在允許的值域內隨機即可.

D Buying gifts

\(n\) 個物品 \((a_i,b_i)\) , 需要選擇兩個不同物品 \(x,y\) , 使得其他的物品要麼 \(a_i < a_x\) , 要麼 \(b_i < b_y\) , 使得 \(|a_x-b_y|\) 最小.

把它畫到二維平面上, 就意味著我們要用兩個半平面覆蓋所有特殊點, 如圖所示.

image

我們列舉 \(x\) (也就是藍點), 他會覆蓋他左邊的所有點, 那要想覆蓋其他的點, 這個點的 \(b\) 就不能小於右側紅點的 \(b\) (也就是說所有紅色點都是合法決策點).

這樣的話, 我們用 set 維護左邊的所有點的 \(b_i\), 在合法範圍內 (高於右側紅點) 尋找最接近於 \(a_i\) 的即可.

注意有 \(a_i\) 相同時的邊界情況.

E Music Festival

我們考慮動態規劃, 每一段數列能成為最大值的數的個數是有限的, 比如 \([1,3,2,4,5]\) 的可能就只有 \([1,3,4,5],[3,4,5],[4,5],[5]\) 總共 \(4\) 種.

所有可能的這樣的序列個數不會很多, 這個數\(cnt \leq \sum n_i \leq 2 \times 10^5\).

發現我們只關心每一個可能段的最小值 \(l_i\) , 最大值 \(r_i\) , 長度 \(w_i\), 因此我們可以把所有的這樣的序列收集起來, 按照 \(l_i\) 排序, 再用動態規劃去模擬拼接的過程.

\[f_i = \max_{j<i \wedge r_j < l_i>}(f_j) + w_i \]

這是個類似於二維偏序的 dp , 用 BIT 維護即可.

F The way home

我們發現, 最優策略形如在一個地方 \(x_{i}\) 一直賺錢, 跑路, 在另一個地方 \(x_{i+1}\) 一直賺錢, 跑路...

其中滿足 \(c_{x_1} < c_{x_2} < \dots < c_{x_k}\)

這是因為如果後面的 \(c\) 更小, 那麼把這次賺的錢放到前面去賺只要更少的次數就能完成, 更優.

這樣, 我們設 \(f_{u,best}\) 表示目前走到 \(u\) , 上一次賺錢是在 \(best\) 的最優策略.

一個最優策略用一個二元組表示 \((t_i,re_i)\) 表示目前賺錢 \(t_i\) 次, 剩餘 \(re_i\) 塊錢.

但是無法比較二元組之間的優劣怎麼辦?

我們發現貪心的先保證 \(t_i\) 更小, 再保證 \(re_i\) 最大一定更優.

為什麼呢? 因為所有方案 \(re_i\) 都會小於 \(c_{best}\) (如果大於等於那就可以少賺一次錢.), 那麼 \(t_i\) 小的方案就可以再演出一次得到方案 \((t_i+1,re_i+c_{best})\) , 這個二元組會完爆掉 \(t_i\) 較大的方案, 因此貪心是對的.

這個轉移只會從 \(t_i\) 小的轉移向 \(t_i\) 大的, 因此用類似於 dijkstra 的方式轉移即可.

G Gasoline prices

快跑啊孩子, 這題卡常

我們用並查集去維護相等關係, 然後每一個不一定相等的元素決策, 乘法原理即可.

我們發現有效的相等關係連邊只會有 \(n-1\) 次(樹的邊數是 \(n-1\) ), 這樣, 問題轉化為如何快速找到有效的連邊位置.

我們發現, 對於一次鏈操作, 我們把每個點的點權看成他的並查集代表元, 如果一個字首鏈都是無效的, 那麼字首鏈的權值連起來形成的串是一樣的.

那麼我們只要每次都二分+雜湊去做就可以了, 維護雜湊用樹剖就可以了.

最後的問題是一次 merge 好多個點的點權都會變, 怎麼辦呢? 啟發式合併! 兩個 log 就做完了.