ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

ARC082 F - Sandglass

問題
提出コード

解法

クエリが時間順で並んでいるので、時刻を進めながらクエリに答えていくことを目指します。
時刻tのクエリに答えるには、r_{i} \lt tとなるようなr_{i}の中で最大の時刻まで時を進めて砂の量を調べ、最後にひっくり返す部分だけシミュレートすれば良いです。
よって、それぞれのr_{i}にて、最初の砂の量がaであった場合にどうなっているか、がわかればよいことになります。
また、砂の量をaで始めたにも関わらず途中で砂時計の上部の砂が空になり、全て下部にたまった場合、砂の量は始め0(X)であった場合と同一視できます。
このような状態になるaは、区間になっているので、その境界を見つけることができればよいです。
途中で空にならなかった場合は、砂時計をシミュレートしていった場合の増減を累積和で記録しておくことで、ある時刻r_{i}における砂の量がわかります。
よって、あとは0,Xと同一視できる区間の境界が求まればよいことがわかりました。
まず明らかにr_{i} - r_{i-1} \geqq Xの場合、任意のaが初めから0もしくはXであったとわかります。
そうでない場合も、増減の累積和を確認し、ある時刻に0(X)になるa区間をマージしていくことで、高速に求めることができます。

感想

おおまかな方針はたっていたのですが、細かい部分を詰めるのに結構時間がかかりました。実装もあんまり綺麗ではない?気がするのでもう少しどうにかしたいです。