二維莫隊解題報告

2022-05-24 06:24:12 字數 1462 閱讀 6814

我寫的莫隊教程

其實這是一道bzoj上的題(bzoj2639,貌似是許可權題,反正我看不了),在yali做模擬賽的時候遇到了.

然後在網上查到了幾篇關於這道題的部落格,都和我的做法略有不同...

給你乙個 \(r*c\) 的矩陣,每個點有乙個顏色, \(m\) 個詢問,每次詢問乙個子矩陣內,每種顏色出現次數的平方和。

\(r,c\le 200,m\le 100000\)

首先我們要明白,莫隊究竟在幹什麼。

莫隊其實就是幾個指標在那跳來跳去,每跳一步都需要一定的時間,通過對詢問排序使得指標跳的總次數盡量小。

所以,這題中詢問為 \((x_1,y_1,x_2,y_2)\) ,也就是四個指標在那跳,分別分塊再排序就可以了,即:

//為避免和cmath庫中的y0y1重名,下文中**內的x1,y1,x2,y2都用x,y,xx,yy代替

struct query

for (j=yy+1;jq[i].yy)

for (j=xx+1;jq[i].x)

for (j=yy+1;jq[i].y)

for (j=xx+1;j具體計算清楚非常複雜,這裡只是估算一下.

\(x_1\) 指標的移動次數為 \(o(mb)\),\(y_2\) 指標的移動次數漸進複雜度中含有 \(o\left(\frac\right)\),取 \(mb=\frac\),得到 \(b=nm^}\)

總時間複雜度為 \(o(mlogm+n^2m^})\)

任意乙個空矩陣就可以了,如 \(x_1=y_1=1,x_2=y_2=0\)

#include #include #include #include using namespace std;

const int n=210;

const int m=100010;

void add(int x);

void del(int x);

int r,c,m,b,a[n][n],lsh[n*n],tot,cnt[n*n],ans,out[m];

struct query }

sort(lsh,lsh+tot);

tot=unique(lsh,lsh+tot)-lsh;

for (i=1;i<=r;++i) }

for (i=0;i>q[i].x>>q[i].y>>q[i].xx>>q[i].yy;

q[i].id=i; }

sort(q,q+m);

for (i=0;iq[i].x)

}while (xxq[i].y)

}while (yyq[i].xx)

--xx;

} while (yq[i].yy)

--yy;

} out[q[i].id]=ans; }

for (i=0;ireturn 0;

}void add(int x)

void del(int x)

二維莫隊 二維分塊 bzoj2639 矩形計算

法一 二維莫隊,對n和m分別分塊後,對塊從上到下從左到右依次編號,詢問以左上角所在塊編號為第一關鍵字,以右下角標號為第二關鍵字排序,轉移時非常厲害。o q n sqrt n include include includeusing namespace std define n 201 define ...

一維莫隊模板

強有力的暴力演算法,重點是通過排序來使暴力變快。主要解決區間內計數問題 例題 小b的詢問 用這道題主要是發現它和我做的一道二維莫隊一模一樣 n個數,m個詢問 我們先寫乙個暴力,和平常的不一樣 乙個左邊界,乙個右邊界,記錄每乙個數在這個區間裡的出現次數和答案,對於每乙個詢問,移動到對應區間就可以拿到答...

莫隊演算法學習報告

一直聽說這個神奇的 據說能解決所有區間問題的演算法 今天學習了一下,可能我只做了幾個模板題,覺得不是很難。我覺得這個寫的挺好的 點我 莫隊演算法說起來也是暴力,只不過利用了分塊的思想優雅的把n 2變成了n 1.5,太強了,orz。用乙個小栗子解釋一下分塊的思想 有一棟樓有100層高,給你兩個雞蛋,讓...