歸納(三) 分塊

2022-05-29 04:48:07 字數 1481 閱讀 1469

優雅的暴力

思維難度低下,**難度低下,非常優秀的一種演算法(?)。

實現方法主要是塊與塊之間 \(o(1)*\sqrt\) 查詢,邊角 \(o(\sqrt)\) 暴力查詢。

總複雜度 \(o(\sqrt)\)。

首先需要塊的大小 \(block\) ,和每個下標歸屬於哪個塊 \(belong[i]\) 。

如果需要塊內有序,可以使用 \(std::vector\) 。

區間修改對於整塊使用lazy標記的思想,邊邊角角還是\(o(\sqrt)\)暴力。

查詢同理。

可以說,這是分塊最最經典的一道題了。

因為似乎沒有其他做法?

分好塊,用 \(std::vectorvc[maxn]\) 維護區間的高矮關係。

用 \(std::lower_bound\) 進行查詢。

修改就打標記。

#include#include#include#includeconst int maxn=1e6+5;

class divid_block

void modify(int l,int r,int c)

for(int i=belong[l]+1;i=c) ++ans;

if(belong[l]!=belong[r])

for(int i=(belong[r]-1)*block+1;i<=r;i++)

if(a[i]+delta[belong[r]]>=c) ++ans;

for(int i=belong[l]+1;i其實,只要你沒學過ct,這道題還是很有希望做出來的。

記錄兩個資訊:

\(tim[i]\) 和 \(whe[i]\) 表示:需要跳幾次才能出這個塊,出了這個塊會到哪個點上。

每一次修改彈力係數,最多隻會影響本塊內會跳到這個點上的彈簧。

所以每一次修改就重構塊。

於是就歡樂的解決了這道題。

(至今還沒寫對lct的我就靠這個安慰自己)

#includeconst int maxn=2e5+5;

class divid_block

void build()

return ;

}void modify(int pos,int val)

}int query(int pos)

public:

int work()

else printf("%d\n",query(pos));

}return 0;

}}t;int main()

關於塊的大小,可以參見初中dalao的部落格(我的分塊他教的)

關於分塊最優塊大小的思考

還有他寫的那個上了洛咕**的部落格:

**基礎根號演算法——分塊

lhy %%% 這個 \((a+c)/2\) 在我們機房裡天天吊虐我。

分塊適用範圍很廣,基本僅次於 \(n^\) 暴力。

走投無路時可以考慮哦。

洛谷2801 分塊

題目鏈結 題目描述 教主最近學會了一種神奇的魔法,能夠使人長高。於是他準備演示給xmyz資訊組每個英雄看。於是n個英雄們又一次聚集在了一起,這次他們排成了一列,被編號為1 2 n。每個人的身高一開始都是不超過1000的正整數。教主的魔法每次可以把閉區間 l,r 1 l r n 內的英雄的身高全部加上...

hdu 3400 Line belt 三分套三分)

題意 在乙個二維空間中給出兩條線段ab,cd,線段ab,cd上的運動速度分別為p,q。在這兩條線段之外的空間上運動的速度為r。求從a到d的最短時間。思路 ps 在這種求解方法中,中間運用了比較多的除法,導致精度損失,所以再開方前加乙個eps,防止開方後的值比真實值小。include include ...

三分 三分求極值 HihoCoder 1142

描述 在之前的幾周中我們了解到二分法作為分治中最常見的方法,適用於單調函式,逼近求解某點的值。但當函式是凸形函式時,二分法就無法適用,這時就需要用到三分法。從三分法的名字中我們可以猜到,三分法是對於需要逼近的區間做三等分 week40 2.png 我們發現lm這個點比rm要低,那麼我們要找的最小點一...