Codeforces #426(Div. 2) C - The Meaningless Game
問題
SlastyonaとPushokがヒントなしの数当てゲームをしている。数当てゲームは0回以上のラウンドからなっており、各プレイヤーは最初、得点として1が与えられている。各ラウンドごとに当てなければならない数が与えられ、そのラウンドの勝者の得点は倍、敗者の得点は倍されることになる。個の得点の組が与えられるので、その組が各ゲームの最終結果としてありうるかどうかを判定せよ。
解説
SlastyonaとPushokという名前は長すぎるので以降、それぞれプレイヤーS、Pと呼ぶことにします。後自然数は0を含みます。
まず、当てなければならない数は全て素数であると仮定できます。これは例えばを当てた時の得点倍率が2を2回、5を1回当てた時の得点倍率と等しいことからわかります。
次に一つの素数しか使われていないゲームを考えます。Sが勝った回数を、Pが勝った回数を、Sの最終得点を、Pの最終得点をとすると、このとき、と表すことができます。これより与えられた入力がゲームの結果としてありうるということは、ある自然数が存在して、、を満たすことに言い換えられるようになりました。
ここで、ある自然数、が存在して、かつを満たすことというのは、かつかつを満たす自然数が存在することと同値です。この命題について証明します。
⇒方向については、とより、自然数が条件を満たすことが明らかです。
逆を示します。とおきます(ただし、、は自然数)。より、が成り立ち、さらにかつよりかつが成り立ちます。このとき、かつを満たすような自然数が存在することを示します。
、より。であるから。ゆえに。
とより。が自然数であることと、よりは自然数。同様にして上の連立方程式の解である自然数が存在することも示せます。よって逆も示すことができました。
以上より、ある自然数、が存在して、かつを満たすこと、すなわち最終結果がとなるようなゲームの進行方法が存在するということは、かつかつを満たす自然数が存在することと同値であるということが示せました。
上の考察は一つの素数のみ使われていたゲームについてのものでした。しかし異なる素数は独立に考えることができるということに気づくと、ゲームで使われた任意の素数それぞれについて上の条件が成り立っているかどうかを調べればよいことがわかります。よって複数の素数が使われているゲームに対してもの立方根に対して、かつが成り立つかどうかを調べればいいことがわかりました。立方根は二分探索で求めることができるので、以上よりの解法を得ることができました。
ソースコード
int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { ll a, b; scanf("%lld %lld", &a, &b); ll ok = 0, ng = 1500000LL; while (ng - ok > 1) { ll mid = (ng + ok) / 2; if (mid * mid * mid <= a * b) { ok = mid; } else { ng = mid; } } ll c = ok; if (c * c * c == a * b && a % c == 0 && b % c == 0) { puts("Yes"); } else { puts("No"); } } return 0; }
感想
コンテスト中はこんなだらだら証明を書かないで、適当に変形して「どうせ必要十分だろ!w」と思って投げたら通りました。