有些問題從起點出發難以前進,從終點逆算過程卻意外的容易。
記得有時倒著做比正著做更容易。
如果從 出發,很難確定下一步應該 還是該 ,畢竟 成長雖快,但歪掉時很難修正回來,例如剛好乘進 再多一些些的地方時。
但反過來從終點就很簡單了:
每次的抉擇可以直接由奇偶來決定,只要 的計算量;最多 次抉擇就會將 砍半,因此過程最多 次,複雜度為 。
直接暴力處理的話,每次加入一個點後,重新計算每一段的長度,需要 的計算量來維護,整體 。
插入一個新的點會導致大量的資料搬動,且必須維持遞增使得容易找出最接近的兩個位置,以找到該切點所影響的線段;
每次切分會導致原有的線段會變短,要維護當前的最長線段,必須能支援刪除最大值後仍能找到下一個最大值。
以上這些都是必要,但目前所學的資料結構難以應對的部份。具體來說必須做到以下:
以上任一動作都必須執行 的次數,因此每個動作都必須在 等級的計算量完成,否則都有 TLE 的可能。
當然,仰賴目前進度未學過的強大資料結構的話,並不是做不到。只是現在做不到。
考慮一開始先把所有切點放進去,再從最後一個切點開始還原,就變成是把一個一個線段接回去。
維護每個切點的左右鄰居,則和鄰居的距離即為線段的長度,如上圖;刪除切點 時左鄰居 右側從 變成 、右鄰居 的左側從 變成 ,用 linked-list 的概念可以處理。
還原時會產生新線段,長度 ,直接和當前最長線段比較,即可維護。刪除舊的點維護最長很困難,但加入新的點維護最長很容易。
排序後即可知道所有切點在最後和誰相鄰。
得到做法如下:
預處理 sort 需要 ,計算過程窮舉 個點,每個點透過二分搜尋 找到在 中的位置,修改左右鄰居 ,總複雜度 。
競程:二章後半
, 競程