優雅的暴力思維難度低下,**難度低下,非常優秀的一種演算法(?)。
實現方法主要是塊與塊之間 \(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要低,那麼我們要找的最小點一...