二分法
维基百科中对二分法的解释:二分法(dichotomy)指的是将一个整体事物分割成两部分。也即是说,这两部分必须是互补事件,即所有事物必须属于双方中的一方,且互斥,即没有事物可以同时属于双方。
所以二分和单调性确实是没有绝对关系的。
二分就是把区间划分成两部分,我把这两部分分别记为left 和 right。满足left就一定不满足right,满足right就一定不满足left。
整数二分口诀:
先r后l l+1,mid那里不加1
先l后r r-1,mid那里要加1
个人是这么记忆的:
如果在else 后写的是r 就要减1,然后在上面的mid那里+1;如果在else后写的是l,就加1,上面的mid就不用加1
//check(mid)是对mid处的数进行判断。
//若符合right,答案就在left。即binarySearch1
//若符合left,答案就在right。即binarySearch2
int binarySearch1(int l,int r){
while(l < r){
int mid = l + (r - 1) / 2; //mid那里不+1
if(check(mid)) r = mid; //先r
else l = mid + 1; //后l l+1
}
return l; //二分到最后一个,即l==r时,为所求
}
int binarySearch2(int l,int r){
while(l < r){
int mid = l + (r - l) / 2 + 1; //mid那里要+1
if(check(mid)) l = mid; //先l
else r = mid - 1; //后r r-1
}
return l; //二分到最后一个,即l==r时,为所求
}
实数二分
double binarySearch3(double l,double r){
double eps;//根据题目设置精度,一般是题目精度的1e-2倍
while(r - l > eps){
double mid = (r + l) / 2;
if(check(mid)) l = mid;
else r = mid;
}
return l;
}
高精度
对于大数,Java可以轻松解决,因为在Java中,math包下有BigInteger这个类
构造器:new BigInteger(String s);
BigInteger a;
BigInteger b;
加法:a.add(b)
减法:a.subtract(b)
乘法:a.multiply(b)
除法:a.divide(b)
取余:a.mod(b)
比较:a.compareTo(b)