一維莫隊模板

2021-10-10 14:08:03 字數 1175 閱讀 4740

強有力的暴力演算法,重點是通過排序來使暴力變快。

主要解決區間內計數問題:

例題:小b的詢問

用這道題主要是發現它和我做的一道二維莫隊一模一樣

n個數,m個詢問

我們先寫乙個暴力,和平常的不一樣:

乙個左邊界,乙個右邊界,記錄每乙個數在這個區間裡的出現次數和答案,

對於每乙個詢問,移動到對應區間就可以拿到答案。

這麼做是o(nm),超時。

這個時候就用到莫隊精髓了--排序。

現將每乙個座標分成從小到大b組,

現將左下標按組號排序,組內

偶數組:右下標從小到大。

奇陣列:右下標從大到小。

這樣排可以得到

對於同一組內的移動:

左下標每次最多移動b次,右下標總共最多移動n次。

換塊時:

左下標每次最多移動2*b次,右下標移動最多n次。

in total:

左下標最多移動了q*b次,右下標移動n*(n/b)次(n/b為換塊次數)

o(q*b+n*n/b)

將b取o(q*sqrt(n)+n*sqrt(n))

那前面為什麼奇偶排序呢?

這樣就可以在r返回的時候做一組

這個就是++,--什麼的,會快很多

**:

#includeusing namespace std;

#define mod (998244353)

#define ll long long

#define m (50005)

#define isdigit(x) ((x) >= '0' && (x) <= '9')

#pragma gcc optimize(3)

ll read()

void write(ll x)

ll belong[m];

struct node

}q[m];

ll n,m,num[m],cnt[m],ans[m],kk;

int main()

sort(q+1,q+1+m);

ll s=0;

ll l=1,r=0;

for(int i=1;i<=m;i++)

for(int i=1;i<=m;i++)

printf("%lld\n",ans[i]);

}

莫隊模板 模板題

也不說了直接上板子 include using namespace std struct quesq 200010 結構體存每個詢問,注意要記錄詢問順序以便輸出 const int block 1300 分的塊大小 int a 30010 ans 200010 res 0 a陣列資料,ans存各個詢...

模板 莫隊演算法

題意 給定乙個大小為n的陣列,陣列中所有元素的大小 n。你需要回答m個查詢。每個查詢的形式是l,r,k。你需要回答在範圍 l,r 中至少重複k次的數字的個數。n,m 100000 誒,這題卡了好久,tle,中間棄了一段,然後今天學弟學莫隊,拿出這個題,他也沒什麼想法,然後我頓時退一步海闊天空了。最開...

模板 莫隊演算法

這個演算法是由之前的國家隊隊長莫濤巨神 orz 發明的,所以尊稱莫隊演算法。如果我們知道區間 l,r 就能在o 1 求出 l 1,r l 1,r l,r 1 l,r 1 的話,那就可以用莫隊演算法了。1 排序,以左段點所在的塊為第一關鍵字,以右端點為第二關鍵字 2 從左往右處理詢問 離線 3 不斷調...