莫隊。。這個聽起來非常高階的東西,當時聽大佬們說這個名詞就一臉害怕,學完發現其實也還好。
之所以叫這個名字 因為發明者的緣故而已。。和演算法本身並沒有什麼直接關係。
莫隊就是用區間來優化暴力,可以把暴力的複雜度壓到n^1.5左右
當然,常數有多大我就不知道了
莫隊演算法的本質就是暴力列舉。
對於m個詢問,就是把m用一種方法排序後,直接暴力
考慮一下,,如果說我們知道 l~r之間的答案,
那麼可以用o(1)的時間來得到l-1~r,l~r+1的答案
所以對詢問排序啊!
好。。我知道會被一些極端資料卡死o(n^2)
但是反之,對於另一種極端情況是不是可以很快?o(n)
莫隊的作用就是讓複雜度均攤,於是就出現了o(n^1.5)
排序方法就是:分塊
例如我們將n個數分成長度為n^0.5的n^0.5(+1)塊
然後按每個詢問的l所在區間排序
是不是就可以了?
每次跳乙個區間的複雜度最多不過是n^0.5而已
我用lin[i]表示第i個數所在區間,排序的判斷如下:
inline bool cmp(node x,node y)
接下來,就是暴力了。。
是不是感覺很簡單=v=+
下面以bzoj3289 mato的檔案管理為例
傳送門——bzoj3289
題意:給定乙個序列a[1..n],詢問l到r區間內逆序對數量
逆序對。。第一反應merge。。然而顯然不可行
然後看了黃學長的部落格,才想到樹狀陣列求逆序對
樹狀陣列:
inline int lowbit(int x)
inline int get(int x)
inline void add(int x,int v)
我們可以記錄rank[i]表示a[i]在公升序序列中的位置
那就方便了啊,當要用l~r求l~r+1的時候,就可以add(rank[r+1],1),反之,求l-1~r時,就可以add(rank[l-1],-1);
於是就變成了一道莫隊的水題啊。。在n^1.5複雜度內解決問題
inline void doit()
for(;r>q[i].r;r--)
while(l>q[i].l)
while(rq[i].ans=ans;
}}
接下來輸出:
inline
bool cmp2(node x,node y)
sort(q+1,q+m+1,cmp2);
for(int i=1;i<=m;i++)
printf("%d\n",q[i].ans);
code:
#include
#include
#include
#include
#include
using namespace std;
struct node
q[50001];
int a[50001],t[50001],lin[50001],f[50001];
int n,m;
intread()
while(ch>='0'&&ch<='9')
return
x*f;
}inline bool cmp2(node x,node y)
inline bool cmp(node x,node y)
inline int lowbit(int
x)inline int get(int
x)inline void add(int
x,int v)
inline void doit()
for(;r>q[i].r;r--)
while(l>q[i].l)
while(rq[i].ans=ans;
}}int main()
int block=sqrt(n);
//tot=tot+(block%n!=0);
for(int i=1;i<=n;i++)
lin[i]=(i-1)/block+1;
doit();
sort(q+1,q+m+1,cmp2);
for(int i=1;i<=m;i++)
printf("%d\n",q[i].ans);
}
複雜度證明:
顯然,l向前移動不會超過乙個區間的長度。所以l最多移動次數:n^1.5,此時每次向前移動都移動至區間最右端,並且每次移到最左。
r同理
所以l和r移動次數大約在n*sqrt(n)的範圍內,接下來就是乘上每次修改的複雜度了,以上題為例,複雜度在極端情況下為n*sqrt(n)*log(n)
這就是莫隊演算法了。。
謝謝看到這裡
莫隊演算法 普通莫隊 智慧型暴力例題模板
1 基礎莫隊演算法2.莫隊演算法實現 莫隊演算法把排序做了簡單的修改,就把暴力法的複雜度從o mn 提高到o n n 1 暴力法的排序 把查詢的區間按左端點排序,如果左端點相同,再按右端點排序。莫隊演算法的排序 把陣列分塊 分成 n塊 然後把查詢的區間按左端點所在塊的序號排序,如果左端點的塊相同,再...
莫隊 優雅的暴力演算法
例題 牛客暑期訓練營 j 題意描述 輸入一串整數 n 1e5 對於每個詢問 i,j 輸出a 1 a i 以及a j a n 裡數字的種類數,詢問一共q個 n 思路分析 暴力解法,即對於每個詢問均通過遍歷尋找答案,會令複雜度高達o n 2 考慮對其進行優化。我們知道對於詢問 i,j 去掉i對結果造成的...
優雅的區間問題暴力 莫隊演算法
對dalao口中可以 o n 區間內絕大部分無修改離線問題的莫隊演算法,一直處於 好騎 的狀態,最近終於找到了學習的機會,其實感覺,這著實是乙個優雅的暴力。莫隊演算法的大前提,是可以利用已知的 l,r 內的答案,直接得到 l,r 1 l 1,r l 1,r l,r 1 上的答案。以下內容預設上述轉移...