「JOISC 2022 Day4」魚 2
阿新 • • 發佈:2022-04-15
考慮怎麼樣的魚能取得最後的勝利,它一定是不斷貪心地往兩邊吃,能吃就吃。
實現以上過程的一個樸素想法是,對左右兩邊分別維護”有效“單調棧,暴力掃一遍。
考慮用線段樹維護上述過程,思考如何合併區間資訊。
假設有 \(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)\)