1. 程式人生 > 其它 >「JOISC 2022 Day4」魚 2

「JOISC 2022 Day4」魚 2

考慮怎麼樣的魚能取得最後的勝利,它一定是不斷貪心地往兩邊吃,能吃就吃。

實現以上過程的一個樸素想法是,對左右兩邊分別維護”有效“單調棧,暴力掃一遍。

考慮用線段樹維護上述過程,思考如何合併區間資訊。

假設有 \(x\) 條魚能在左子樹中吃完所有的魚,那麼加入右區間後,它們的增廣方向一定是單向的。

這時候發現需要分別維護區間從左和從右開始的“有效”單調棧,也就是維護從左端點或右端點開始吃,在哪些點會停下的棧。

那麼就可以快速判斷能吃光原區間的魚能否在新區間依然取得成功。

可以發現棧大小最多為 \(\log_2V\) 個,因為每次跨過障礙後數值至少乘 \(2\)

還有一種情況是在原區間並不能成功,但是在新區間時通過吃掉另一個區間的一些魚而取得成功。

首先如果它吃不到另一個區間那麼它就永遠不可能吃掉全部。

那麼只需考慮能吃掉一段字首或是字尾的位置,把這些都記在它們第一個不能吃到的位置上。可以發現這些位置都在“有效”單調棧上。

接著考慮如何判斷能否成為答案。

可以發現能成功的點構成一個前/字尾,那麼一個樸素的想法是二分這個位置暴力判斷,時間複雜度為 \(\mathcal O(N\log_2 N\log_2V\log\log_2V)\)

進一步分析可以發現,從小到大列舉若失敗則從斷點開始繼續走,這樣合併區間資訊的複雜度就是 \(\mathcal O(\log_2V)\)

總時間複雜度為 \(\mathcal O(N\log_2V\log_2N)\)