設定越界下標確定是否存在
1從學oi到現在,二分思想是逐漸發揮其威力的。其思想跟數學歸納法很像://>=x
2while(l
<==x
8while(l
//setprecision(3)
15while(l+(1e-5)
1621 for(i,0,100)22
並不直接解決問題,而是將問題轉化為幾個相同的規模較小的問題。對於很簡單的子問題(邊界條件),直接給出答案。
對於高階資料結構,像線段樹,平衡樹都是基於二分思想
可以說,二分是演算法大樓的重要根基之一。
用二分法配合基礎演算法打暴力,往往會有意想不到的收穫。
對於有單調性的序列,二分能夠在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;b. chebnear2 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 }
最近,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,再取...