解説
1からNまでの自然数のうち、(aの倍数)∩(lcm(a,b)の倍数でない) となるような自然数の数を求めれば良いです。
- 1からNまでの自然数のうちのkの倍数の個数は N/kを整数値に切り捨てた値としてO(1)で求めることができます。
- lcm(a,b) は gcd(a,b)の値をユークリッドの互除法を利用して求めることでO(log(max(a,b)))で求めることができます。
以上のことから、答えを求めることができます。時間計算量はユークリッドの互除法がボトルネックとなり、O(log(max(a,b))) です。コンピューターは一秒に 106 回の計算ができるため、 本制約においては余裕を持って実行時間制限に間に合います。 よって、この問題を解くことができました。
追記
この問題の制約において、C++のlonglong型の最大値(約9×1018) を lcm(a,b) が超えてしまうことが考えられます。よって、C++のような固定長の整数を扱う場合は次のように考えます。
- lcm(a,b)=gcd(a,b)ab より、N<lcm(a,b)
つまり、N<gcd(a,b)ab⟺bN<gcd(a,b)a のとき lcm(a,b)で割り切れる1からNまでの自然数は0個 と判定、そうでなければ実際にlcm(a,b)で割り切れる1からNまでの自然数の数を求める、という感じで実装することでオーバーフローを回避しながら計算を進めることができます。