二分这玩意,整数型的总是会搞错额。。
今天终于算是搞懂了,在题目中再多磨练磨练把。
推荐博客:http://www.cppblog.com/converse/archive/2009/09/21/96893.html
个人倾向于写法是:
while(l<r),所以我的这种写法是属于左闭右开区间的那种类型。
那么if(a[mid]>v)时,我应该写成r=mid,因为右边是开的,如果写成r=mid-1,则会遗漏a[mid-1]的情况。
else时,应该写成l=mid+1,因为左边是闭的,而且当前条件不成立,所以直接往右移就好。
昨天那道poj1505:
要求的是值尽量小,所以ans初始化为inf,
然后:
ll bin(ll x,ll y){
ll ans=inf;
while(x<y){
ll mid=x+(y-x)/2;
if(is_ok(mid)){
y=mid;
ans=min(ans,mid);
}
else x=mid+1;
}
return ans;
}
因为我们要求的是mid,所以只需要更新ans就好了。
昨天那道cf299div1的A题,则要求的是尽量大的值。
然后:
ll bin(ll x,ll y){
ll mid;
ll ans=-1;
while(x<y){
mid=x+(y-x)/2;
if(is_ok(mid)){
x=mid+1;
ans=max(ans,mid); //二分的时候可以用一个变量来保存结果!
}
else y=mid;
}
return ans;
}
这里x+1的原因是因为当前x已经满足了,而且我们用了一个ans保存下来了中间结果mid,所以x可以往后去推了,所以x+1。
而上面那个x+1的原因是因为当前x不满足了,所以答案肯定在后面,所以x+1。