莫隊與分塊精簡小結

2022-05-07 20:18:08 字數 1432 閱讀 9706

我覺得我還要補上帶修莫隊,樹上莫隊等等……(先咕著……)

分塊:引用範圍廣,實現簡潔(注意塊的邊界)一般為\(\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,裸的線段樹板子 分塊的思路...