2019年9月18日水曜日

AGC 026 B - rng_10s

AGC 026 B - rng_10s

とりあえず自明ケースを除いておく:

  • A<BA < BならNo
  • B>DB>DならNo
  • 上記以外でBCB \le CならYes

それ以外の場合では、Noになるのは在庫の数XXが区間(C,B)(C, B)に入ってしまう場合、つまり1回の購入量BBより小さく補充の閾値CCよりは大きい状態が発生してしまうケースである。これはXXmod  B\mod BC+1,C+2,...,B1C+1, C+2, ..., B-1のいずれかと合同になる、と言い換えられる。

シミュレーションしながら考えてみる:

  • 最初の在庫AAmod  B\mod BC+1,C+2,...,B1C+1, C+2, ..., B-1のどれかと合同だとNo。
  • A0,1,...,Cmod  BA \equiv 0, 1, ..., C \mod Bの場合はDD個の補充に成功する。A+DA+Dmod  B\mod BC+1,C+2,...,B1C+1, C+2, ..., B-1のどれかと合同だとやはりNo。
  • A+D0,1,...,Cmod  BA+D \equiv 0, 1, ..., C \mod Bの場合はさらにDD個の補充に成功する。A+2DA+2Dmod  B\mod BC+1,C+2,...,B1C+1, C+2, ..., B-1のどれかと合同だとやはりNo。

というわけで、非負整数xxが存在してA+DxA+DxC+1,C+2,...,B1C+1, C+2, ..., B-1のいずれかと合同の場合()(*)はNo、それ以外はYesとわかる。

これで解けたと思ったのだが、そこから先のやり方がよくわかっていないことに気づいて考えこんでしまった……

合同方程式を解く方法に立ち戻る。A+Dxdmod  BA+Dx \equiv d \mod Bを解くことはDx+By=dADx+By = d-Aを解くことと同じで、後者が可解であることはdAd-Agcd(B,D)\gcd(B, D)の倍数であることと同値である。1 したがって、条件()(*)C+1A,C+2A,...,B1AC+1-A, C+2-A, ..., B-1-Aの中にgcd(B,D)\gcd(B,D)の倍数が含まれる、と言い換えられる。これなら実装可能な判定方法になっている。つまり、gcd(B,D)\gcd(B,D)の倍数でC+1AC+1-A以上であるような最小のもの2を求めてそれがBAB-A未満ならNo、そうでなければYesである。


  1. xxが非負という条件は考える必要がない。整数解があれば必ずxxが非負整数の解もあるため。 ↩︎

  2. yy以上のxxの倍数で最小のものは、式としてはxy/xx \cdot \lceil y/x \rceilと書ける。 ↩︎