膜拜duyi! && CF1436E題解

Cherrt發表於2020-11-02

這篇文章參考了神仙 d u y i duyi duyi的題解。個人認為他的那篇文章寫得比這篇還要好,可以去看看他的這篇題解如果看不懂的話 ,就來看看我的。

sto duyi orz!!!
duyi ddjxd!

Description

求一個序列的所有連續區間的 m e x mex mex m e x mex mex

Solution

Part 1: 轉化

首先,看到本題,我們不難想到三個思考方式:

①直接從 m e x mex mex m e x mex mex入手,挖性質;
②從 m e x mex mex入手,擴充套件到 m e x mex mex m e x mex mex
③拆分這兩個 m e x mex mex

從①入手,似乎並沒有什麼用。
從②入手呢?很顯然, m e x mex mex就是一個區間中最小的,沒有出現的數。
從③入手呢?結合②,我們似乎完成了一個轉化:

⌊ \lfloor 對於每一個值 x x x,我們要判斷是否存在一個區間的 m e x mex mex等於 x x x ⌉ \rceil

我們從 1 1 1 n + 1 n+1 n+1列舉每一個 x x x,如果不存在這樣的區間使得它的 m e x mex mex等於 x x x,那麼就直接輸出 x x x並結束即可。

現在的難點,在於如何判斷是否存在一個區間的 m e x mex mex等於 x x x

Part 2: 決策包容性(貪心)

再重複一遍 m e x mex mex的定義: m e x mex mex就是一個序列中最小的未出現的數。

即,一個區間的 m e x mex mex如果要等於 x x x,需要滿足兩個要求:
①這段區間沒有 x x x
②這段區間有 1 , 2 , 3 … … , ( x − 1 ) 1,2,3……,(x-1) 1,2,3,(x1)

我們需要以①,②中的一個為條件,另一個為要求去尋找這樣的區間。

我們考慮以更加簡單達到的①為條件。我們找出所有 x x x(可以預處理),可以發現任意兩個 x x x均不能出現在同一個區間中。

為了滿足②,可以發現一個“單調性”:如果一個區間有 1 1 1 x − 1 x-1 x1這些數,那麼它的子區間不一定有;如果它的子區間有,那麼它一定有。

所以,我們對於劃分出來的這些區間,分別求一下 m e x mex mex即可。如果這些 m e x mex mex都不等於 x x x,那麼這些大區間的子區間顯然都無法滿足要求。

可以發現,對於不同的 x x x,劃分出來的區間的數量的級別只有 n n n。於是,我們只需要完成下面這種操作: ⌊ \lfloor n n n次查詢一段區間的 m e x mex mex ⌉ \rceil

Part 3: 離線,莫隊套權值線段樹上二分

對於這種查詢一段區間的 m e x mex mex的題目,我們有一個套路: 莫隊

然後,每次我們單點修改(add/delete),區間查詢 m e x mex mex的時候直接線段樹上二分即可。

修改的時間複雜度是 O ( n n log ⁡ n ) O(n \sqrt n \log n) O(nn logn),查詢的時間複雜度為 O ( n log ⁡ n ) O(n \log n) O(nlogn),總時間複雜度為 O ( n n log ⁡ n ) O(n \sqrt n \log n) O(nn logn)。由於資料範圍是 n ≤ 1 0 5 n≤10^5 n105,無法通過。

Part 4: 離線,莫隊套分塊,“根號平衡”

可以發現,修改操作足足有 n n n \sqrt n nn 個,而查詢操作只有 O ( n ) O(n) O(n)。但是,用線段樹做修改與查詢操作都是單次 log ⁡ \log log級別的,那我們能不能“犧牲查詢的複雜度,來優化修改操作的複雜度”呢?

答案是可以的,分塊可以搞定。對於每次修改,由於是單點的,我們直接 O ( 1 ) O(1) O(1)打上標記即可;對於一次查詢,我們掃一遍所有的塊,如果這一塊沒有被填滿,顯然 m e x mex mex的值在這一塊內;然後我們暴力掃描一下這一塊即可。

單次修改的複雜度為 O ( 1 ) O(1) O(1),單次查詢的複雜度為 O ( n ) O(\sqrt n) O(n )

總時間複雜度 O ( n n ) O(n \sqrt n) O(nn ),本題被完美解決。

Summary

毫無疑問,這是一道絕世好題。而 d u y i duyi duyi巨佬能切掉這題,足見他之神仙;而我卻冥思苦想 1 h 1h 1h,只想到了第一個 P a r t Part Part中的東西,足見我有多菜。

我們從 m e x mex mex的定義本身,考慮轉化為“查詢是否存在一個區間的 m e x mex mex等於 x x x”,又通過貪心的決策包容性,轉化為了“查詢一段區間的 m e x mex mex”,緊接著使用經典的莫隊套權值線段樹上二分來得到了本題的“正解”,可惜時間複雜度多了一個 log ⁡ \log log。最後,根據一個套路,我們考慮到了“根號平衡”,即對於“修改與查詢不平均”的問題都可以考慮下分塊是否可以優化。

dylstxdy!

Code

咕咕咕

相關文章