二分與三分

2022-05-20 09:51:47 字數 2008 閱讀 1593

設定越界下標確定是否存在

1

//>=x

2while(l

<==x

8while(l

//setprecision(3)

15while(l+(1e-5)

1621 for(i,0,100)22

從學oi到現在,二分思想是逐漸發揮其威力的。其思想跟數學歸納法很像:

並不直接解決問題,而是將問題轉化為幾個相同的規模較小的問題。對於很簡單的子問題(邊界條件),直接給出答案。

對於高階資料結構,像線段樹,平衡樹都是基於二分思想

可以說,二分是演算法大樓的重要根基之一。

用二分法配合基礎演算法打暴力,往往會有意想不到的收穫。

對於有單調性的序列,二分能夠在o(logn)的時間內進行查詢。

具體應用:

1. 二分查詢

binary_search(a+n1,a+n2,k);true 找到 ,false 沒找到

lower_bound(a+n1,a+n2,k[,cmp])

可以排在值的後面

upper_bound(a+n1,a+n2,k[,cmp])

必須排在值的後面

2、二分答案

對於最大值最小化和最小值最大化的問題,可以二分答案,利用答案倒推。

經典例題

a. tree

給你乙個無向帶權連通圖,每條邊是黑色或白色。求一棵最小權的恰好有 need 條白色邊的生成樹

wqs二分

p2619 [國家集訓隊2]tree i

1 const int mx=100010;

2 struct edgee[mx];

3 int fa[50010];

4 intn,m,k,l,r,mid,ans1,cc,t;

5 voidscan()

6 9 }

10 boolcmp(edge aa,edge bb)

11 14 int findf(int x)

15 bool mg(int x,inty)

16 21 }

22 boolkruskal()

23 35 if(t==n-1) break;

36 }

37 return ans1

38 }

39 voidwork()

40 49 mid=l;kruskal();

50 cout

51 }

b. chebnear

最近,r終於獲得了一片他夢寐以求的農場,但如此大的一片農場,想要做好防衛工作可不是一件容易的事。所以r購買了n個守衛,分別讓他們站在一定的位置上(守衛不可移動,同一位置上至多有乙個守衛)。但是,安排了所有的守衛之後,r才發現,守衛們彼此十分厭惡。經r研究,當某兩個守衛距離≤k,他們就會發生爭吵;但是,想要守衛們和解也是不難的——只需要r給出的平均工資能使兩人滿意,他們就會同意和解、成為朋友;當然,如果兩個守衛有共同的朋友,他們也會和解成為朋友。r非常不想守衛們爭吵,因此他想找出,在能使所有守衛閉嘴的前提下,平均工資的最小值是多少。他想到了乙個絕妙的方法,但他忙著去farm,沒時間,所以這個任務就交給你了。

sort邊權值,從小到打拿 二分選邊條數,每次判斷不在同一聯通快中中點的最小距離

4. 三分法

mid1=l+(r-l)/3;mid2=r-(r-l)/3;

對於單峰函式,最優點會與好點在壞點同側

5. 分治解題

color zed的刷子寬度只有1,也就是說,一次只能將連續的一排或一列格仔塗上顏色(長度任意)。zed想用最少的次數把柵欄全部塗上顏色(注意,乙個格仔不能重複塗色)

我理所當然的想用dp做,但是有特殊情況

解決辦法:每次不斷往上壘,碰到中斷的地方就分治解決,分別列舉

(其實不需要離散化,>5000的直接丟掉即可)

二分與三分

其實二分,三分與分治的思想差不多,都是對乙個問題的分段操作 前提為有序 qwq 二分法,在乙個單調有序的集合或函式中查詢乙個解,每次分為左右兩部分,判斷解在哪個部分中並調整上下界,直到找到目標元素,每次二分後都將捨棄一半的查詢空間,因此效率很高。例如,對於在實數區間 l,r 內遞增的連續函式f x ...

二分與三分

分值的思想 opj用longlong include include include include include using namespace std long long n long long a1 100005 int m long long a2 10005 int main scanf...

二分與三分查詢

一 二分查詢 二分查詢很常見了,放乙個模板就溜。時間複雜度 o logn log以2為底。最後得到的是可行域的閉區間 l,r while r l 二 三分查詢三分查詢用於查詢乙個凸 凹 函式的極值點。時間複雜度 o 2 logn log以3為底。對於乙個區間 l,r 先取中點mid l r 2,再取...