一種高階科技,在noi2020day1t3**之後,不會\(a\)部分分(裸·區間逆序對)的餘下定決心要好好學習根號演算法。
二次離線莫隊聽名字就是個非常高階的東西,而且雖說是二次離線,但它的複雜度仍舊是\(o(n\sqrt n)\),非常神奇。
一般用於移動左右端點時複雜度較大的莫隊。
例如區間逆序對,它有乙個非常顯然的莫隊+樹狀陣列的\(o(n\sqrt nlogn)\)做法,原因就是每次移動端點時要在樹狀陣列上詢問。
而二次離線莫隊可以完美解決這個問題。
假設當前左右端點為\(l,r\),現要將右端點向右移一位。
考慮這次移動之後,答案的變化值就是\([l,r]\)中大於\(a_\)的數的個數。
這東西可以拆成兩個:\([1,r]\)中大於\(a_\)的數的個數減去\([1,l-1]\)中大於\(a_\)的數的個數。
其中前面那個東西顯然可以樹狀陣列\(o(nlogn)\)預處理。
而後面這個東西,我們可以對於每個位置開乙個\(vector\),然後把\(r+1\)連同當前詢問的編號一同扔到\(l-1\)的\(vector\)中。
根據莫隊的複雜度證明,我們一共會移動端點\(o(n\sqrt n)\)次,這樣的記憶體可能會有點大。
然而我們發現,假設乙個詢問需要我們把\(r\)向右移到\(r'\),移動過程中\(l\)是保持不動的,因此實際上我們可以直接把\([r+1,r']\)整個區間連同詢問編號一起扔到\(l-1\)的\(vector\)中。這樣一來記憶體就是\(o(n)\)級別的了。
把移動區間扔到\(l-1\)的\(vector\)中的過程,就是第二次離線。
然後我們只要從左到右列舉每乙個位置,處理該位置\(vector\)中的詢問。
注意雖然我們存的是區間,但詢問時依舊要列舉區間中的每乙個數乙個個詢問,詢問次數依舊是\(o(n\sqrt n)\)的。
又由於我們只會列舉\(1\sim n\)這\(n\)個位置,因此可以考慮適當增加修改的複雜度以實現\(o(1)\)詢問。
於是就想到\(o(n\sqrt n)\)修改、\(o(1)\)詢問的分塊。
這樣就徹底解決了整個問題。
具體實現中,由於左端點移動和右端點移動答案變化值詢問範圍相反,因此很多東西都要開兩個。
第二次離線:列舉每乙個位置,處理\(vector\)中的詢問。
最後,給答案做個字首和(因為我們求出的只是答案變化值),然後輸出。
預處理(樹狀陣列):\(o(nlogn)\)
第一次離線(莫隊):\(o(n)\)(因為此時我們沒必要再一點一點移動端點,直接一步到位就可以了)
第二次離線(分塊):\(o(n\sqrt n)\)(修改單次複雜度\(o(\sqrt n)\),次數\(o(n)\);詢問單次複雜度\(o(1)\),次數\(o(n\sqrt n)\))
總複雜度:\(o(n\sqrt n)\)
(如有不對請指出~~~)
毒瘤lxl的題目讓我感受到深深的惡意,果然noi這種東西還不是餘現在的水平能夠挑戰的。。。
無刪除莫隊與二次離線莫隊
大佬部落格 無刪除莫隊 沒打過但是可以拿來湊數。不就是用可回退化 你一定需要看一看 十二省聯考2019 希望 的莫隊來。skip。二次離線莫隊 一開始看是ynoi的題以為沒有啥可拓展性。然後看了上面那位大佬的部落格才發現這個方法大有可為。莫隊實際上是把o m o m o m 個詢問拆分成o n m ...
洛谷 P4887 模板 莫隊二次離線
原題鏈結 給定乙個長度為 n 的序列和乙個常數 k 每次詢問乙個區間 l,r 內,有多少對 i,j 滿足 l leq i,且 a i oplus a j 的二進位制表示下恰好有 k 位為 1 資料範圍 1 leq n,m leq 10 5,0 leq a i 2 0 leq k leq 14 按照普...
HH的項鍊 第二彈(莫隊 離線)
同樣的我們依舊進行離線並對詢問進行排序,以左端點所在塊為第一關鍵字,以右端點為第二關鍵字。這樣可以減少大幅度移動次數 我們以樣例為例 資料1 2343 5編號12 3456 塊號112 233提問 1.1,2 2.2,6 3.3,5 那麼我們就要兩個移動下標f1,f2。其實位置為0,0 隨著問題的討...