莫隊演算法小結以及模板題

2022-05-26 22:03:08 字數 1672 閱讀 3815

被splay折磨了乙個星期還是抄模板都wa,除錯的時候查資料都發現資料太大不能查的蒟蒻楊瀾決定學習莫隊演算法,

但是萬萬沒想到

莫隊也到處都是坑

----------------------------------------------題記

莫隊這個東西就是乙個非常簡♂單的類似動規的東西,也是那種不會就一直不會,一看題解秒懂的題,[雖然我看題解也半天看不懂但是只是第一道題,萬事開頭難嘛(也許吧)]

莫隊演算法是一種基於分塊的離線演算法,主要用來解決一些區間的詢問[就是暴力],我們需要做的就是把詢問都存下來然後適當的排序,分塊,把內容相近的詢問放在一起集中處理[利用前面得到的資料來處理詢問]以節省時間...說了像沒說一樣..但是這個東西的原理就是醬..

我們先按照左端點排序,然後分塊。

然後在每個塊內按右端點排序。

然後順序處理即可。

塊內複雜度:

因為塊內右端點是遞增的,所以右端點至多變化o(n)次,而左端點 不一定,所以是o(l*l)=o(n)次。

塊間跳**撐死了o(n)。

總複雜度:o(n^1.5)。

↑大神ppt裡的東西複製下來了...果然比我寫的清楚一萬倍

那麼接下來是第一題

模板題...大神的程式和題解.第二題這裡也有喵

題目 : 給定長度為n的數列以及正整數,有m個詢問每次詢問給定兩個數l,r,求l≤i≤j≤r,且a(i) xor a(i+1) xor a(i+2) xor ... xor a(j)=k的(i,j)的個數。

輸入 : 輸入資料第一行為n,m,k,意義如題所示。

第二行n個正整數,第i個數表示這個數列a的第i項。

接下來m行,每行兩個整數,表示詢問操作的l和r。

輸出 : 輸出資料報含m行,表示每個詢問的答案。

樣例輸入

6 2 3

1 2 1 1 0 3

1 63 5

樣例輸出70

首先我們要回憶一下已經忘光了的位運算中異或的小知識

我們所需要的重要的一條就是,異或就是其自身的逆運算, a^b^a=b , a^a=0 , 0^a=a;

那麼我們就可以用陣列a[i]來儲存字首(異或)和來處理這個東西了.......

下面說的x到y的異或和的意思就是a(x) xor a(x+1) xor a(x+2) xor ... xor a(y)

↓**的一部分

1 p=(int)sqrt(m*1.0);2

for(int i=1;i<=m/p;i++)9/*

從異或的性質可以知道如果a[r]^k=z,那麼z^a[r]=k;

10cnt[z]指的是o∈(l,r](左開右閉是因為l宣告為0...)滿足從第1到第o個數的異或和是z的o有多少個...好麻煩...

11那麼為什麼是+cnt[z]?

12因為a[r]是從1到r的異或和,如果a[r]^乙個1到o的異或和=k,那麼從o到r的異或和就是k

*/13

while(l1)

14while(l>e[j].x-1)

15 e[j].ans=ans;16}

17 }

view code

異或真是個磨人的小妖精啊![棒讀]

tbc接下來的1p應該是襪子那道題...

莫隊模板 模板題

也不說了直接上板子 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 不斷調...