強有力的暴力演算法,重點是通過排序來使暴力變快。
主要解決區間內計數問題:
例題:小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 不斷調...