莫隊演算法的學習

2021-08-22 07:07:45 字數 1528 閱讀 7262

問題

給定乙個長度為n的序列,然後對m個區間[l,r]進行查詢。

解題:

離線區間問題,莫隊無敵。

對m個查詢按照 l 所屬的塊號(塊的大小為sqrt(n))為第一優先順序、r的大小為第二優先順序排序。

然後根據當前的區間[l,r]的答案去推導出下乙個區間[l』,r』]的答案。

這樣,每查詢乙個區間,需要移動abs(l-l『)+abs(r-r』)次。

而移動一次的時間複雜度一般是o(1)的(用陣列去存)或者o(logn)的(用map去存)。

總的時間複雜度為o(n*sqrt(n) )。

hh有一串由各種漂亮的貝殼組成的項鍊。hh相信不同的貝殼會帶來好運,所以每次散步 完後,他都會隨意取出一

段貝殼,思考它們所表達的含義。hh不斷地收集新的貝殼,因此他的項鍊變得越來越長。有一天,他突然提出了一

個問題:某一段貝殼中,包含了多少種不同的貝殼?這個問題很難回答。。。因為項鍊實在是太長了。於是,他只

好求助睿智的你,來解決這個問題。

input

第一行:乙個整數n,表示項鍊的長度。

第二行:n個整數,表示依次表示項鍊中貝殼的編號(編號為0到1000000之間的整數)。

第三行:乙個整數m,表示hh詢問的個數。

接下來m行:每行兩個整數,l和r(1 ≤ l ≤ r ≤ n),表示詢問的區間。

n ≤ 50000,m ≤ 200000。

output

m行,每行乙個整數,依次表示詢問對應的答案。

sample input

61 2 3 4 3 5

1 2

3 52 6

sample output

2

#include 

using namespace std;

const int maxn=1e6+7;

const int maxm=2e5+7;//詢問次數

int n,m;

//map

buf;o(logn)會超時

int buf[maxn];//資料範圍較小,用陣列o(1)。

int block;//塊的大小

struct query

query(){}

bool operator<(const query &o)const

void erase(int

x)int a[maxn];//原陣列

int main()

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

memset(buf,0,sizeof(buf));

sum=0;

int l=1,r=1;//l,r表示當前buf裡計數的範圍

insert(a[1]);

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

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

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

}return

0;}

莫隊演算法學習筆記(一) 普通莫隊

前言 在學習莫隊演算法之前,我一直以為這是乙個很高深的演算法。實際上,它就是乙個很高深的演算法 這個演算法玄學地將分塊與暴力兩大演算法實現了二合一,從而打造出了乙個時間複雜度為o n n o n sqrt n o nn 的求解多個區間詢問的離線演算法。具體介紹 首先,我們以詢問中l ll所在的區間為...

莫隊演算法學習筆記(三) 樹上莫隊

樹上莫隊的核心思想,就是將一棵樹轉化成乙個序列,然後用普通莫隊來搞。以一棵樹為例 要想對這棵樹進行樹上莫隊,我們第一步就是用乙個 s 陣列把它的括號序存下來 id 12 3456 78910 1112 1314 1516 s 12 4788 7455 2366 31 同時,我們用 i 陣列儲存每個數...

莫隊演算法學習筆記(二) 帶修莫隊

莫隊演算法,是乙個十分優雅的暴力。普通的莫隊可以輕鬆解決一些離線問題,但是,當遇上了一些有修改操作的問題,普通莫隊就無能為力了。於是,改進後的莫隊 帶修莫隊就這樣產生了。接下來,我們一起在普通莫隊的基礎之上,學會帶修莫隊這個強大無比的演算法。既然是帶修莫隊,那麼第乙個關鍵問題就是如何處理修改。其實,...