莫隊演算法 初探總結

2022-03-17 15:03:01 字數 2069 閱讀 2262

莫隊演算法分那麼幾類:

其實上述的型別還可以組合起來(非常的毒瘤)。

個人理解莫隊演算法的精髓在於如何利用暴力將答案再合理的時間和空間內跑出來。說白了:

\[莫隊演算法=一種很牛逼的自定義排序+分塊處理+暴力

\]

bool cmp(const node &a,const node &b)

排完序後大致移動的次數就在可控的範圍內了。

其次是分塊,因為一般這種序列題的複雜度是\(o(\frac+ms)\) (\(n\)是序列長度,\(m\)是詢問次數,\(s\)是塊大小)。

那麼用均值不等式去分析這個複雜度就好了。一般\(n\),\(m\)同階的時候取\(\sqrt n\)最優,但是假如\(n\)和\(m\)有別的情況的話具體分析,有時候還要決定用時間換空間來保證空間也過得去。

之後就是暴力,想辦法怎麼通過指標的移動(進入和離開所求區間\([ql,qr]\))的時候統計答案。

這個要看基本功了(很多時候就是數學功底)。

一般這個複雜度要盡量的低,最好是\(o(1)\),否則會影響整體的複雜度。

下面我們具體情況具體分析一下:

沒什麼好說的,直接套板子,有時候維護不了了就想想變化量是什麼,其實只用知道變化量是什麼其實都不太難了。

好像只用在原有的基礎上加上一維表示時間即可。但是塊大小應該不能是\(n^\)了,這樣會將整體複雜度退化成\(o(n^2)\)。塊大小可以取\(n^}\)或者是\(n^}\)。

帶修改的莫隊,其實相當於普通的兩個指標的莫隊加了乙個新的指標表示時間軸,一般時間軸的移動放在前兩維之後。而且要注意一點,對於時間軸上的修改操作,我們一般只交換序列中的資訊和修改陣列裡面的資訊,因為這樣可以方便下一次時間倒回來的時候重新修正資訊。

再談奇偶排序,可以用,將第三維奇偶排序也是可以的,但是按照個人經驗,實測沒有多大的提公升,有時候反而更慢,所以建議不用。

回滾莫隊一般用於解決一類看似普通莫隊,但是很方便加入資訊對答案的維護,但是不方便維護刪除資訊對答案的維護。又或者是只方便刪,但是不方便加的一類序列問題。這樣的普通的莫隊就無能為力了。

回滾莫隊的思想,還是利用排序,令某一邊的指標單調地變化,另外乙個指標暴力移動。

分塊後,具體地:(這裡只討論左右端點不同塊的情況,同塊的可以直接暴力解決,時間過得去的)

不過要注意幾個初學者理解起來常見的問題。

只加不減和只減不加是什麼意思?是真的不能加(減)嗎?不是的。對於有一些計數器等等的,還是需要具備求逆運算的能力,只不過不方便維護答案而已。又好比上述的暴力復位操作,都是需要逆運算將貢獻減掉的,只不過不用在暴力復位的時候想著還原答案而已(因為你可以先存一下當前的答案,然後再做暴力的那一部分,做完的那個答案是用另外乙個東西來存的,這樣就不影響了,可以放心復位了)。

不可以用奇偶排序。因為這樣就打破了回滾莫隊的本質,為什麼?很容易想的,仔細看上述分析就懂了。

一般的樹上莫隊,是可以先求出尤拉序,然後轉化為序列上的問題去解決。還有一些像什麼子樹統計的莫隊,那種我認為用樹剖+線段樹大力維護可能更方便些,複雜度也更優秀。

假如是樹鏈型的樹上莫隊,先求出尤拉序,準備好lca。然後對於詢問,假如問的是\(u,v\),那我們欽定\(u\)的\(dfs\)序比\(v\)小,那麼假如lca是\(u\)的話,用\(first_u\)到\(first_v\)來表示樹鏈,否則用\(second_u\)到\(first_v\)表示樹鏈,但是要注意第二種情況下,lca是沒有被統計到的,這裡一定要加上特判。(此處的first和second表示第一次/第二次訪問那個節點時的編號)。

談一下注意事項:

要開\(2n\)的空間,因為\(dfs\)序存下的序列都是倍長了的。

個人經驗,這裡的加還是刪就不是我們能夠個人判斷的東西了,因為乙個序列中某個點經過兩次,就代表這個點的子樹其實已經被訪問完了,對答案其實沒有什麼影響,所以不是加兩次貢獻,而是應該刪掉之前的貢獻。所以這裡是應該維護乙個\(bool\)陣列,表示每個樹上點的訪問狀態,每次異或,根據那個訪問狀態來決定操作到底是加還是刪。對於那些帶修改的也是同理,那個點還是用陣列標記來看加/刪,假如發現原來就沒有的,那也不必改了,因為答案不會有變化,否則就調整那個變化(但是兩種情況下都要swap原始值和修改值,前者只不過是不用add/del而已)。

大家看情況拼起來就行了,還是靠大家動手實踐。

總結 莫隊演算法

機房中的各位神仙都會莫隊就我不會,然後如果有些題實在想不出也可以用這個做一下。如果一些操作可以在知道 ans l,r 的情況下,o 1 的時間內求出 ans l 1,r ans l 1,r ans l,r 1 ans l,r 1 那麼就可以用莫隊求解。將操作離線 按照分塊的思路排序 這是保證複雜度合...

莫隊總結 莫隊例題

假設我們已知區間 l,r,需要計算的區間為 l,r,由於 l 和 r分別只能單步轉移,所以需要的時間複雜度為 l l r r 相當於把兩個區間分別看成是平面上的兩個整點p1 l,r 和p2 l,r 兩點之間的轉移開銷為兩點之間的曼哈頓距離。連線所有點的最優方案為一棵樹,那麼整體的時間複雜度就是這棵樹...

莫隊入門總結

這是一篇適合蒟蒻的講解 大佬可以自行離開 莫隊是一種是離線的演算法 即它在詢問的時候是不會修改的,所以我們可以通過調整詢問的次序來獲得答案。比如區間3到5和區間3到6 他們之間只差了1 於是我們只需要看下新加進來的這個元素對原來答案的影響就好了 對吧?問題是 我們應該如何給詢問區間排序使得時間複雜度...