莫隊演算法可以乙個可高效解決絕大多數離線+無修改+區間查詢問題的演算法。這類問題具體是指:如果知道[l,r]的答案時,可以在o(g(n))的時間下得到[l,r−1],[l,r+1],[l−1,r],[l+1,r]的答案的話,就可以o(n
n⋅g(
n)
)o(n\sqrt n · \mathrm(n))
o(nn⋅
g(n)
)的時間內求出所有查詢。
假設我們算完[l,r]的答案後現在要算[l′,r′]的答案。由於可以在o(1)的時間下得到[l,r−1],[l,r+1],[l−1,r],[l+1,r]的答案,所以計算[l′,r′]的答案耗時|l−l′|+|r−r′|。如果把詢問[l,r]看做平面上的點a(l,r),詢問[l′,r′]看做點b(l′,r′)的話,那麼時間開銷就為兩點的曼哈頓距離。
具體實現
我們先對序列分塊,每塊長度為sqrt(n),然後以詢問左端點所在的塊為第一關鍵字,右端點的大小為第二關鍵字進行排序
然後每個區間由它的上乙個區間推出來,雖然單次詢問仍可能是o(n),
但是在塊中每次詢問l的移動最大為sqrt(n),r的移動總和最大為n,塊與塊之間的移動最大為n
所以總複雜度為o((n+m)sqrt(n))
我這裡給出莫隊的模板,
#include
#include
#include
#include
#include
#define n 50010
#define ll long long
using
namespace std;
int n, m, k, unit;
struct mo
} a[n]
;int b[n]
, cnt[n]
;ll ans[n]
;int
main()
sort
(a +
1, a +
1+ m)
;int l =
1, r =0;
ll ans =0;
for(
int i =
1; i <= m; i++
)while
(r < a[i]
.r)while
(l < a[i]
.l)while
(r > a[i]
.r) ans[a[i]
.id]
= ans;
}for
(int i =
1; i <= m; i++
)printf
("%lld\n"
, ans[i]);
return0;
}
不知道該怎麼辦
今天,她徹底爆發了。但是,我能如何呢,我只有選擇保守的做法。每天上班其實還是挺累的,回來呢又面對這些事情,我總感覺我馬上就要到地獄一樣。前途似乎都是一片黯淡。十多萬的事情都出來了,這樣的事情我真的害怕了。心裡面有說不出的滋味,我不曉得我那天回崩潰,但是那一天總會到來。也許我會大哭一場呢。現在還是想原...
我也不知道寫什麼
上海師範大學教育學院教授 這早就不是秘密 在我國中小學的語文課裡,幾乎沒有寫作教學。據我們所知,中小學的 作文教學 主要在兩個階段 一是在寫之前指導學生審題,或使學生進入寫作的情景,或有構思的激發乃至 訓練 這一階段主要解決 寫什麼 的問題,對 怎麼寫 只有原則性的引導或要求。二是在寫之後,教師對學...
我也不知道是什麼題
題意 給出平面上n個點 n 300 都在第一象限且沒有重複的,保證座標都是整數 合法的點集滿足如下要求 1 6個點,並且有4個點在x軸上 2 這六個點可以組成兩個三角形並且兩個底角都是銳角 3 乙個三角形被另乙個完全包含 畫張圖 有點醜 qaq 分析 我的第一想法是列舉座標軸上的4個點 然後想想就暴...