二分模板大全
阿新 • • 發佈:2019-02-15
#include<iostream> #include<cstdio> using namespace std; const int MAXN = 100005; int mi[MAXN][50];//Çø¼ä×î´óÖµ£¬Çø¼ä×îСֵ¡£ int lg[MAXN]; int num[MAXN]; //精確查詢---用遞迴實現二分查詢,精確查詢目標元素的位置,假定陣列遞增排列,且不存在重複元素 int bsearch1(int low,int high,int target){ if(low > high) return -1; int mid = low + (high - low)/2; if(num[mid] > target){ return bsearch1(low,mid-1,target); } if(num[mid] < target){ return bsearch1(mid+1,high,target); } return mid; } //精確查詢---用迭代的方式實現二分查詢,精確查詢目標元素的位置,假定陣列遞增排列,且不存在重複元素 int bsearch2(int low,int high,int target){ while(low <= high){ int mid = low + (high - low)/2; if(num[mid] > target){ high = mid -1; } else if(num[mid] < target){ low = mid + 1; } else{ return mid; } } return -1; } //界限查詢----用二分查詢尋找上屆,正好大於目標數的那個數(嚴格界限,不包含自身) int bsearchupperbound(int low,int high,int target){ if(low > high || target >= num[high]){ return -1; } while(low < high){ int mid = low + (high - low)/2; if(num[mid] > target){ high = mid; } else{ low = mid + 1; } } return high; } //界限查詢---用二分查詢尋找上屆,正好大於等於目標數的那個數(鬆散界限,可以包含自身) int bsearch5(int low,int high,int target){ if(low > high || target > num[high]){ return -1; } while(low < high){ int mid = low + (high -low)/2; if(num[mid] >= target){ high = mid; } else{ low = mid + 1; } } return high; } //界限查詢---用二分查詢尋找下屆,正好小於目標數的那個數(嚴格界限,不包含自身) int bsearchlowerbound(int low,int high,int target){ if(low > high || target <= num[low]){ return -1; } while(low < high){ int mid = (low + high + 1) / 2; //這裡用向上取整,否則陷入死迴圈 因為low無法往上爬超過high if(num[mid] < target){ low = mid; } else{ high = mid -1; } } return low; } //界限查詢---用二分法尋找下屆,正好小於等於目標的那個數 (鬆散界限,可以包含自身) int bsearch6(int low,int high,int target){ if(low > high || target < num[low]){ return -1; } while(low < high){ int mid = (low + high + 1)/2; if(num[mid] <= target){ low = mid; } else{ high = mid - 1; } } return low; } //用二分查詢找尋區域,找到目標元素出現的下標範圍,允許重複元素(先找到嚴格上屆和嚴格下屆) int results[] = {-1,-1}; void searchRange(int low, int high,int target,int len){ if(low > high){ return ; } int lower = bsearchlowerbound(0, len, target); lower = lower + 1; if(num[lower] == target){ results[0] = lower; } else{ return ; } int upper = bsearchupperbound(0, len - 1, target); upper = upper < 0 ? (len - 1) : (upper -1); results[1] = upper; return ; } //二分查詢ST表 void ST_prework(int n){ for(int i=1 ; i<=n ; ++i)mi[i][0] = num[i];//ϱê´Ó1¿ªÊ¼ //int t = log2(n) + 1; for(int i=2;i<=n;i++)lg[i] = lg[i/2] + 1; int t = lg[n] + 1; for(int i=1 ; i<t ; ++i){ for(int j=1 ; j<=n-(1<<i)+1 ; ++j){ mi[j][i] = min(mi[j][i-1],mi[j+(1<<(i-1))][i-1]); } } } int ST_query(int l,int r){//[l,r]±ÕÇø¼ä int k = lg[(r-l+1)]; return min(mi[l][k],mi[r-(1<<k)+1][k]); //·µ»ØÇø¼ä×îСֵ } int bsearch7(int l,int r){ int re = num[l++]; int ll,rr,tmp,mid,flag; while(l <= r && re){ flag = 0; ll = l,rr = r; mid = l; while(ll<=rr){ mid = (ll + rr)/2; if(ST_query(ll,mid) <= re){ rr = mid-1;tmp = mid;flag = 1; }else if(ST_query(mid,rr) <= re){ ll = mid+1;tmp = mid;flag = 1; }else{ break; } } if(flag){ re = re % num[tmp]; l = tmp+1; }else break; } return re; } int main(){ return 0; }