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;
}



この記事が気に入ったらサポートをしてみませんか?