化暴力為標算 莫隊

2021-07-27 08:57:54 字數 2501 閱讀 1081

莫隊。。這個聽起來非常高階的東西,當時聽大佬們說這個名詞就一臉害怕,學完發現其實也還好。

之所以叫這個名字 因為發明者的緣故而已。。和演算法本身並沒有什麼直接關係。

莫隊就是用區間來優化暴力,可以把暴力的複雜度壓到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 上的答案。以下內容預設上述轉移...