AGC047 A - Integer Product 解いてみた
こんにちは、あるたいるです。
AGC047 の日本語解説がまだ出ていないことと、自分とおなじ考え方をしている人が少なそうだったので、初めて解説記事を書いてみます。正直、エレガントではないですが(main関数が80行くらいある…)、非常に気持ちよく解けたので自慢させてください。かなり素直な発想が多いので、腑に落ちやすいと思います。
問題概要
個の実数が与えられる。積が整数になる2数のペアの個数は?
制約
は小数部の桁数が以下
考えたこと
まず、小数のままではいろいろとマズそうなので、文字列として受け取って何かするはず。 倍すれば整数になるが、この数は最大で くらいになるから、2数の積を考えるとオーバーフローするのでなんだかやな感じ。そうすると、分母が である分数で表すしかない。けれど、これなら「2数の積が整数」を簡単に表現できる。
分数は全て既約分数にする(ただし分母が1のときは残す)。分母と分子のGCDで割ってやれば良い。その上で、 が整数になる必要十分条件を考えると、 と 、 と が互いに素であることから、「 が の約数かつ が の約数」であることはすぐにわかる。
そうすると、分子の約数を列挙したいと思うのが自然な発想。しかし、分子は最大で である。普通に列挙すれば の1要素につき となり、到底間に合わない。どうしよう?
ここで、これらの分数の分母は、もともと であったことに注目しよう。すると、分母の取りうる値はごく少ないことに気づく。すなわち、 の約数である! の約数はたったの 個しかないので、 列挙すべき分子の約数もその 個の中にあるものだけでいいのである。
それでは、 個の分母を全探索しよう。ある の約数 について考える。分母が である分数 について、 とペアになる可能性があるのはどの分数か? 当然、列挙した分子の約数の中に が存在する分数である。この分数は1つとは限らないが、その一つを とする。 と がペアになるためには、 の分子の約数の中に、 の分母が含まれていれば良い。同じ分母を持つ分数について事前に計算をしておけば、複数の を同時に処理できる。 は高々 個であるので、計算量は で抑えられる。
あとはダブルカウントに注意して(の場合など)処理すれば、答えを導くことができる! 実際には map などを多用しているので計算量に がついてしまうが、やろうと思えば map はいらないはず。というかもっと綺麗に書けるだろ…
列挙するのは の約数だけでいいことに気づくところが山ですが、「同じものをまとめて考える」というのは二重ループを解消する時にしょっちゅう使われる手法なので、わりと思いつきやすいかなと思います。たのしかった〜!!