這種優化只能對於在擴充套件縮小區間維護答案時,查詢的東西是可以差分的,並且只能優化掉修改的複雜度;
比如你在查乙個區間的逆序對,當你擴充套件右端點時,你需要將答案加上前面這段區間中比新的右端點位置上的值大的個數,這種查詢就是可以差分的,比如我們當前的區間的左右端點為l,r
l,rl,
r,那麼我們擴充套件右端點就可以先查[1,
r][1,r]
[1,r
]中比r+1
r+1r+
1這個位置上的數大的個數減去[1,
l−1]
[1,l-1]
[1,l−1
]中比r+1
r+1r+
1位置上的數大的個數;
然後對於這種型別的莫隊,他的修改複雜度很大時,因為我們最多要修改(n+
m)∗n
(n+m)*\sqrt n
(n+m)∗
n次,所以根本接受不了;這個時候考慮再次把這(n+
m)∗n
(n+m)*\sqrt n
(n+m)∗
n次修改的詢問離線下來並且差分,這樣只需要對著序列掃一遍,修改n
nn次就可以了,但是你查肯定還是要查(n+
m)∗n
(n+m)*\sqrt n
(n+m)∗
n次;但是往往空間可能會比較吃緊,畢竟有(n+
m)∗n
(n+m)*\sqrt n
(n+m)∗
n次修改的查詢,再次考慮莫隊移動區間的性質:它每次移動的都是一段連續的區間;我們還是考慮移動右端點,此時的區間是l,r
l,rl,
r,我們要把右端點移動到r+k
r+kr+
k這個位置上;
可以發現r+1
r+1r+
1到r+
kr+k
r+k這段位置他們差分後的查詢都有乙個減去[1,
l−1]
[1,l-1]
[1,l−1
]的貢獻,然後另一半都是減去[1,
擴充套件出的
位置−1
][1,擴充套件出的位置-1]
[1,擴充套件出
的位置−
1]的貢獻;那麼我們直接把r+1
r+1r+
1到r+
kr+k
r+k這段區間直接離線到l−1
l-1l−
1這個位置上去;然後對於後面那種,我們可以維護乙個這樣的東西f[i
]=[1
,i−1
]對i的
貢獻f[i]=[1,i-1]對i的貢獻
f[i]=[
1,i−
1]對i
的貢獻,然後求個字首和,這樣空間就被優化成了線性的;動左端點同理,也是這麼去幹,去推一下離線到哪就行了;但是前乙個把區間離線到對應節點上去,還是要列舉區間那麼長乙個個去查詢,所以還是得查詢(n+
m)∗n
(n+m)*\sqrt n
(n+m)∗
n次;最終我們莫隊的複雜度由原來的o((
n+m)
∗n∗(
修改複雜
度+查詢
複雜度)
)o((n+m)*\sqrt n *(修改複雜度+查詢複雜度))
o((n+m
)∗n
∗(修改
複雜度+
查詢複雜
度))變成了現在的o(n
∗修改復
雜度+(
n+m)
∗n∗查
詢複雜度
)o(n*修改複雜度+(n+m)*\sqrt n *查詢複雜度)
o(n∗修改
複雜度+
(n+m
)∗n
∗查詢復
雜度),這樣我們就把每次莫隊擴充套件所變化的值預處理好了,每次擴充套件縮小區間o(1
)o(1)
o(1)
修改;這個思想來自於luogup4487;lxl大毒瘤
做了這題然後沒幾天就在codeplus三月的月賽上用到了,優化了乙個log的複雜度下來成功用假演算法a了個題;
關於一些莫隊的總結
最近學了一些莫隊的應用,先總結如下。對於某一些莫隊,當它的修改操作複雜度較高,又具有可差分的性質時,我們可以考慮如下優化方法 給莫隊詢問操作對應的修改操作 二次離線 具體來說,設當前左右指標為nl,nr,現在的詢問左右指標為ql,qr,有 1.ql lt nl delta sum ans 1,r i...
莫隊演算法的學習
問題 給定乙個長度為n的序列,然後對m個區間 l,r 進行查詢。解題 離線區間問題,莫隊無敵。對m個查詢按照 l 所屬的塊號 塊的大小為sqrt n 為第一優先順序 r的大小為第二優先順序排序。然後根據當前的區間 l,r 的答案去推導出下乙個區間 l r 的答案。這樣,每查詢乙個區間,需要移動abs...
HH的項鍊 莫隊
hh 有一串由各種漂亮的貝殼組成的項鍊。hh 相信不同的貝殼會帶來好運,所以每次散步完後,他都會隨意取出一段貝殼,思考它們所表達的含義。hh 不斷地收集新的貝殼,因此,他的項鍊變得越來越長。有一天,他突然提出了乙個問題 某一段貝殼中,包含了多少種不同的貝殼?這個問題很難回答 因為項鍊實在是太長了。於...