1. 程式人生 > >關於分塊演算法and莫隊演算法

關於分塊演算法and莫隊演算法

先說分塊演算法(這是一個線上的演算法)

我們將長度為n的序列分為sqrt(n)個小塊

對於每個詢問區間[l, r], 有些塊是完全包含其中的,有些塊是部分包含的

對於完全包含其中的塊

我們可以預處理出答案

對於部分包含的塊

我們可以暴力求解

這樣,每次詢問的複雜度即為O(n sqrt(n))

至於修改的操作

同上,我們至多用sqrt(n)的時間即可解決

該演算法的題目有:

                BZOJ2724 求區間眾數(強制線上)

                BZOJ2821 求區間出現正偶數次的數的總數(強制線上)

                BZOJ3343 將區間內的數加上X and 求區間內不小於X的數的個數

再來講莫隊演算法(這是一個離線演算法and不支援複雜的修改操作)

也是將長度為n的序列分為sqrt(n)個小塊

對於每個詢問區間[l, r]

以 l所在的塊 為第一關鍵字,r 為第二關鍵字排序

對於當前詢問Que[x].l,Que[x].r ,

我們可以以 O(|Que[x].l-Que[x-1].l|+|Que[x].r-Que[x-1].r|) 的複雜度

由Que[x-1].l,Que[x-1].r推來,可以證明演算法複雜度為 O(n√n)

我們也可以用莫隊演算法實現簡單的修改操作,

即建立一個時間軸,

將每個詢問 <l,r,time> 

以 l所在的塊 為第一關鍵字, 

r所在的塊 為第二關鍵字,

time 為第三關鍵字排序

每個詢問依舊從上一個詢問推來

這樣的演算法複雜度為O(n^2)

該演算法的題目有:

                BZOJ1878 求區間內出現的數的種數

                BZOJ2038 求區間內兩數相同的概率

                BZOJ3781 求區間內數的出現次數的平方和

分塊演算法和莫隊演算法的內容大致如此
剩下的只有靠多刷題啦