關於整數二分的筆記

2022-07-12 04:57:13 字數 1513 閱讀 9850

題目:

給定乙個按照公升序排列的長度為n的整數陣列,以及 q 個查詢。

對於每個查詢,返回乙個元素k的起始位置和終止位置(位置從0開始計數)。

如果陣列中不存在該元素,則返回「-1 -1」。

輸入格式

第一行包含整數n和q,表示陣列長度和詢問個數。

第二行包含n個整數(均在1~10000範圍內),表示完整陣列。

接下來q行,每行包含乙個整數k,表示乙個詢問元素。

輸出格式

共q行,每行包含兩個整數,表示所求元素的起始位置和終止位置。

如果陣列中不存在該元素,則返回「-1 -1」。

資料範圍1≤

n≤100000

'>1≤n≤100000

1≤n≤1000001≤

q≤10000

'>1≤q≤10000

1≤q≤100001≤

k≤10000

'>1≤k≤10000

1≤k≤10000

輸入樣例:

6 3

1 2 2 3 3 434

5

輸出樣例:
3 4

5 5-1 -1

思路

這個題目是需要尋找對於給定數的左邊界與有邊界位置,對於這樣乙個有序數列,可以選擇用二分:

當尋找左邊界時,將mid賦值以l+r>>1;(此處的l和r為每次二分的左邊界和有邊界)再根據處在

mid位置的值來確定下次尋找邊界為左半邊還是右半邊。最後當l==r時,尋找結束,若此時的l(

或者說是r,因為此時l==r,結束條件是l不大於r)對應的數與尋找的數不相等,則證明這個數並

不在這個數列裡面,就輸出「-1 -1」,如果相等,則證明至少有乙個被尋找的數在這個數列當中,

此時先輸出左邊界。而尋找右邊界時,mid就不應該是l+r>>1,而是l+r+1>>1,對於這個尋找

左右邊界的區別,可以考慮當尋找的最後,l和r只相差1的時候,在尋找左邊界的時候,會形成

死迴圈。

模板:

(預設為公升序數列)

尋找左邊界:

x為要尋找的數

while(l>1;

if(a[mid]>=x)r=mid;

else l=mid+1;

}尋找右邊界:

while(l>1;

if(a[mid]<=x) l=mid;

else r=mid-1;

}完整**:

#include

using namespace std;

int a[100010];

int main()

while(q--)

if(a[l]!=x) cout<<"-1 -1"<>1;

if(a[mid]<=x) l=mid;

else r=mid-1;

}cout<}

模版 整數二分

確定乙個區間,使得目標值一定在這個區間內 從題目中找到一種性質 根據上述的性質,具體可以把整數二分劃分為兩大類問題 第一類 目標值是前半段的右端點 將 l,r l,r l,r 分成 l,mid 1 l,mid 1 l,mid 1 和 mi d,r mid,r mid,r 如果mid midmi d處...

C Convoy(整數二分)

這道題我直接好傢伙,方法就是二分時間,看看最短時間符不符合。坑在於 1.需要判斷a i 是否等於0,不然有時候會re!2.需要注意司機無論多少趟只能帶乙個。因為回來的時候也需要乙個人開車。3.左右邊界盡量開到1e12。而且變數以防萬一都開long long,不然會超時。include using n...

整數二分詳解

在公升序 無重複元素的陣列中,查詢值為k的元素的陣列下標 include include include using namespace std const int n 10 在給定陣列中查詢k值所在位置,若不存在則返回 1 l為二分下界,r為二分上界 intbinarysearch int a,i...