B - 花束
[Q] https://atcoder.jp/contests/arc050/tasks/arc050_b
にぶたん。方針はわかるけど…実装にとても苦しんだ(5WA)
Q. 何を二分探索するの?
A. 花束の総本数。
1. 最初に赤束を全部作ると仮定。(赤い花は不足しててもいい。)
2. 残った青い花をもとに、青束を最大まで作成する。( 青束を最大まで作れば、赤い花の使用量を最小にできる。)
3. 最後に赤い花の数で実際に作成可能か判定。( 2.で赤い花の最小消費が出せている)
Q. オーバーフロー?
A. 素直に処理すると1e18 * 1e9 をしてしまう場面が発生してしまうので、式変形。
ll R, B, x, y;
int main(){
cincout();
cin >> R >> B >> x >> y;
ll high = oo;
ll low = -1;
while (high-low > 1){
ll mid = (high + low) / 2;
ll b=B;
// ll r-=mid*x; // オーバーフロー
b -= mid; // まずmid本全部、赤束にする。
if (b<0){ // この時点で青不足してたらもうダメ。
high = mid;
continue;
}
ll ycnt = min(b/(y-1), mid); // mid本より多くは作らない
if (ycnt > R){ // 青束だけで赤の本数を超える=赤束0にしたのに、青束の赤すら補えない
high = mid;
continue ;
}
// r = R + (x-1) * ycnt - x*mid; オーバーフロー
// R+(ycnt-mid)*x - ycnt<0; ならr不足でダメ。
if (ycnt-mid < (ycnt-R)/x) high = mid;
else low = mid;
}
cout << low << endl;
}