我覺得我還要補上帶修莫隊,樹上莫隊等等……(先咕著……)
分塊:引用範圍廣,實現簡潔(注意塊的邊界)一般為\(\sqrt\)分塊。
塊中可維護很多東西,維護資訊時從後往前處理。
例題:\(hnoi2010\)彈飛綿羊
#includeusing namespace std;
#define s(x) ((x)*(x))
inline int read()
while(x!=eof&&x>='0'&&x<='9')
return w*f;
}const int n=2e5+10;
int n,m,cnt,siz;
int k[n],typ[n],tim[n],end[n];
struct lump lum[n];
inline void prepare(int l,int r)
int main()
else k=read(),k[j]=k,prepare(lum[typ[j]].l,lum[typ[j]].r);
}}
莫隊:帶有分塊思想的優化暴力。
例題:\(sp3267d-query\)
考慮乙個優化:用兩個指標移動,來計算答案,指標移動到和詢問重合時記錄答案。
優化操作**:(\(sum\)為不同元素個數,\(tag\)為記錄的桶,\(num\)為元素型別)
while(lp[i].l) sum+=(!(tag[num[--l]]++));
while(rp[i].r) sum-=(!(--tag[num[r--]]));
但是這樣仍然會被卡死,考慮對詢問排序。如果是一般的排序,顯然還是會導致被卡。
如何寫\(cmp\),我們可以對\(1\sim n\)分塊,如果兩個區間左端點在同乙個塊內,按右端點排序,如不在,按左端點在的塊排序。複雜度不會證……這是乙個講的較好的詳解
有乙個小小的常數優化,就是分奇偶性排序,左端點在同乙個奇數塊中,按右端點從小到大排,在同乙個偶數塊中,按右端點從大到小排序,不在同乙個塊中按塊排序。
#includeusing namespace std;
inline int read()
while(x!=eof&&x>='0'&&x<='9')
return w*f;
}const int n=1e6+10;
//maptag;
struct region p[n];
int n,m,siz,cnt,sum,num[n],typ[n],ans[n],tag[n];
inline bool cmp(region x,region y)
int main()
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}
莫隊階段小結
首先,為什麼要叫小結呢,因為我只學了一點點,後續可能更多 莫隊是一種離線處理區間問題的神器.答題思路就是你將原數列分成 sqrt 塊,將所有查詢左端點定位,並按照左端點所在的塊進行排序,相同則按照右端點排序 大體就是這個樣子 inline bool cmp q x,q y 這樣的話我們每個快內都暴力...
bzoj3585 莫隊 分塊
description 有乙個長度為n的陣列。m次詢問,每次詢問乙個區間內最小沒有出現過的自然數。input 第一行n,m。第二行為n個數。從第三行開始,每行乙個詢問l,r。output 一行乙個數,表示每個詢問的答案。sample input 5 52 1 0 2 1 3 32 3 2 41 2 ...
分塊 莫隊學習粗略預習
分塊 莫隊學習總結 2020 08 12 16 55 32 thumb up 0 大概就是暴力的進化版,採用 大段維護,小段樸素 的思想 拿個板子說事 已知乙個數列,你需要進行下面兩種操作 將某區間每乙個數加上 k。求出某區間每乙個數的和。序列長度為1e5,運算元為1e5,裸的線段樹板子 分塊的思路...