二分(升序的序列才能进行二分操作)
是否可以使用二分法的关键在于:二分后,能否判断出答案所在的区间,而不是数据是否有序。
左边界
//左边界(找到的是最满足条件的数,下一个就不满足条件了)
int l_binary(int k){
int l=0,r=n-1;
while(l<r){
int mid=l+r>>1;
if(a[mid]>=k)r=mid;
else l=mid+1;
}
return l;
}
右边界
int r_binary(int k){
int l=0,r=n-1;
while(l<r){
//向上取要加一,因为加法自动向下取整
int mid=r+l+1>>1;
if(a[mid]<=k)l=mid;
else r=mid-1;
}
return r;
}
小数二分确定范围
double n;
cin>>n;
double m;
double l=-100,r=100;
//边界范围(防止出现小数0.001开根号后0.1,比自己大)
//整数二分边界范围是0-x,
whlie(r-l>1e-8){//比要保留的位数多2比较保险(这个是保留六位小数)
m=(l+r)/2;
if(m*m*m>n)r=m;//缩小范围
else l=m;
}
printf("%.6lf\n",l);
一位前缀和(输出原序列中从第 l个数到第 r 个数的和)
for(int i=1;i<=n;i++){
s[i]=a[i]+s[i-1];
}
//s[N]可能要开long long
二维前缀和(x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。对于每个询问输出子矩阵中所有数的和。)
//计算(x,y)的前缀和
s[i][j]+=s[i][j-1]+s[i-1][j]-s[i-1][j-1];
//计算(x1,y1,x2,y2的前缀和)
ans=s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];