単調性がある場合は二分化する必要があり、単調性がない場合は二分化することもできます
整数バイナリステップ:
1. 区間 [L, R] を見つけて、答えがその区間内にあるようにします。
2. 判定条件が双対性を持つような判定条件を見つけ、その答えが双対性の分岐点となるはずです
3. 判定条件の下で中点 M が成立するかどうかを解析し、成立する場合は答えがどの区間にあるかを検討し、成立しない場合は答えがどの区間にあるかを検討します。
4. 更新メソッドで R=Mid と記述されている場合は処理は必要ありませんが、更新メソッドで L=Mid と記述されている場合は、Mid を計算するときに 1 を加算する必要があります。
二分法テンプレートの最初のタイプ:
ans は緑色の領域の右端点です
[L, R]を[L, M-1]、[M, R]に分割
M が緑色の場合、ans がまだ [M,R] にあることを意味します。
else は ans が [L, M-1] にあることを示します
極限ケースを分析する:
L=R-1
M=(L+R+1)/2=R
R=M-1=R-1=L
コアコード:
while(L<R){
int mid=(L+R+1)/2;
if(mid为绿) L=mid;
else R=mid-1;
}
最初のタイプのテンプレートであるかどうかを判断する方法:
L=M の場合、中点を取るときに +1 が必要になることを意味します、つまり (L+R+1)/2
二分法テンプレートの 2 番目のタイプ:
ans は青い領域の左端点です
[L, R] を [L, M], [M+1, R] に分割
M が青色の場合、ans が [L,M] にあることを意味します
else は ans が [M+1, R] にあることを示します
極限ケースを分析する:
L=R-1
M=(L+R)/2=L
L=M+1=L+1=R
コアコード:
while(L<R){
int mid=(L+R)/2;
if(mid为蓝) R=mid;
else L=mid+1;
}
最初のタイプのテンプレートであるかどうかを判断する方法:
R=M の場合、中点、つまり (L+R)/2 を取るときに +1 する必要がないことを意味します。
本当の二分法:
実際のバイナリ テンプレート:
区間[L,R]を[L,M],[M,R]に分割
ans が左の区間 [M, R] にある場合、L=M
それ以外の場合、ans が正しい区間 [L, M] 内にある場合 R=M
while(L-R>1e-6){
double mid=(L+R)/2;
if(mid为左区间) R=mid;
else L=mid;
}