あるたいるの競プロ手記

競プロについてちまちまと書いています

AGC047 A - Integer Product 解いてみた

こんにちは、あるたいるです。

AGC047 の日本語解説がまだ出ていないことと、自分とおなじ考え方をしている人が少なそうだったので、初めて解説記事を書いてみます。正直、エレガントではないですが(main関数が80行くらいある…)、非常に気持ちよく解けたので自慢させてください。かなり素直な発想が多いので、腑に落ちやすいと思います。

atcoder.jp

 

問題概要

N 個の実数A_1, \ldots ,A_nが与えられる。積が整数になる2数のペアの個数は?

制約

2\leq N\leq 200000

0\lt A_i \lt 10^4

A_iは小数部の桁数が9以下

考えたこと

まず、小数のままではいろいろとマズそうなので、文字列として受け取って何かするはず。10^9 倍すれば整数になるが、この数は最大で 10^{13} くらいになるから、2数の積を考えるとオーバーフローするのでなんだかやな感じ。そうすると、分母が 10^9 である分数で表すしかない。けれど、これなら「2数の積が整数」を簡単に表現できる。

分数は全て既約分数にする(ただし分母が1のときは残す)。分母と分子のGCDで割ってやれば良い。その上で、\frac{b}{a} \times \frac{d}{c} が整数になる必要十分条件を考えると、abcd が互いに素であることから、「 ad の約数かつ cb の約数」であることはすぐにわかる。

そうすると、分子の約数を列挙したいと思うのが自然な発想。しかし、分子は最大で 10^{13} である。普通に列挙すればA_i1要素につき \sqrt{10^{13}} となり、到底間に合わない。どうしよう?

ここで、これらの分数の分母は、もともと 10^9 であったことに注目しよう。すると、分母の取りうる値はごく少ないことに気づく。すなわち、10^9 の約数である! 10^9 の約数はたったの 100 個しかないので、 列挙すべき分子の約数もその 100 個の中にあるものだけでいいのである。

それでは、100 個の分母を全探索しよう。ある 10^9 の約数 d について考える。分母が d である分数 X について、X とペアになる可能性があるのはどの分数か? 当然、列挙した分子の約数の中に d が存在する分数である。この分数は1つとは限らないが、その一つを Y とする。XY がペアになるためには、 X の分子の約数の中に、Y の分母が含まれていれば良い。同じ分母を持つ分数について事前に計算をしておけば、複数の X を同時に処理できるY は高々 N 個であるので、計算量は O(100 \times N) で抑えられる。

あとはダブルカウントに注意して(d = 1の場合など)処理すれば、答えを導くことができる! 実際には map などを多用しているので計算量に log がついてしまうが、やろうと思えば map はいらないはず。というかもっと綺麗に書けるだろ…

 

自分の提出

atcoder.jp

 

列挙するのは 10^9 の約数だけでいいことに気づくところが山ですが、「同じものをまとめて考える」というのは二重ループを解消する時にしょっちゅう使われる手法なので、わりと思いつきやすいかなと思います。たのしかった〜!!