Important!!!
在用三分板子找极大/小值的时候,左右端点(l,r)的取值不能为极大/小值,否则板子返回的不是正确答案,为避免此情况,可令左右端点各往外扩充一步(l=1l=0,r=n
r=n+1,check(0)和check(n+1)返回inf或-inf)
求凹函数的极小值
int tri_search(int l,int r){
// 求凹函数的极小值
int f1,f2;
while(l < r) {
int lp = l + (r - l) / 3;
int rp = r - (r - l) / 3;
f1 = check(lp),f2 = check(rp);
if(f1 <= f2)
r = rp - 1;
else
l = lp + 1;
}
//查找的是极小值
return min(f1,f2);
//查找的是极小值对应的下标
return f1<f2?l:r;
}
求凸函数的极大值
int tri_search(int l,int r){
// 求凸函数的极大值
int f1,f2;
while(l < r) {
int lp = l + (r - l) / 3;
int rp = r - (r - l) / 3;
f1 = check(lp),f2 = check(rp);
if(f1 >= f2)
l = lp + 1;
else
r = rp - 1;
}
//查找的是极大值
return max(f1,f2);
//查找的是极大值对应的下标
return f1>f2?l:r;
}
出现意外情况(靠近边界直接暴力)
// 求凹函数的极小值
int tri_search(int l,int r){
int f1,f2;
while(r - l > 5) {
int lp = l + (r - l) / 3;
int rp = r - (r - l) / 3;
f1 = check(lp),f2 = check(rp);
if(f1 <= f2)
r = rp - 1;
else
l = lp + 1;
}
int res = check(l);
for(int i = l + 1;i <= r; ++i){
res = min(res,check(i));
}
return res;
}