解説はまだ未完成です
二次元の場合
図のように、光の道筋を展開することを考えます。
すると、点 A から発射され、いずれかの頂点で消える光の道筋は、下の図の頂点Aからいずれかの点へ向かう直線に対応していることが分かります。
右上の点 A から下へ x ,右へ y 進んだ地点を (x,y) として、(0,0) と (x,y) を結ぶ線分と対応する光の道筋を考えるとき、光が辺 CD で反射する回数は ⌊2x⌋
であることが分かります。また、その他の辺についても同様に求めることが出来ます。
ただし、x と y が互いに素ではない場合、つまり上の図の黒い点線などの場合、線分の途中に点 C があるので、頂点に当たっているが光が消えないということが起こってします。よって、x と y が互いに素である必要があります。
三次元の場合
二次元の場合と同じ議論をすることにより、この問題は以下の問題に帰着されます。
- 次の条件を満たす正整数 x,y,z の組について、 ⌊2x⌋X⌊2y⌋Y⌊2z⌋Z の総和を求めよ。
- gcd(x,y)=gcd(x,z)=gcd(y,z)=1,x≤2a+2,y≤2b+2,z≤2c+2
しかし、このままでは計算量が O(abclogXYZ) となり、明らかに実行時間制限に間に合いません。
そこで、長さが max(2a+2,2b+2) で Ai=gcd(x,y)=1,lcm(x,y)=i∑(⌊2x⌋X⌊2y⌋Y) である数列 A を考えます。
この数列の各項は O(ablogXY) で求められることが分かります。また、長さが 2c+2 で Bi=⌊2i⌋Z である数列 B を用意します。
また、Ci=gcd(x,y)=i∑AxBy である数列 C を考えます。このとき、求めるべき答えは C1 となります。
このことは、gcd(lcm(x,y),z)=1 であれば gcd(x,y)=1,gcd(x,z)=1 であることを利用し、実際に展開をすると求めるべき答えと一致していることが分かります。
数列 C の値を計算することを考えます。
実は、数列から数列への関数 f(x) を f(x)i=i∣j∑xj で定めるとき、f(A)if(B)i=f(C)i が成立していることが分かります。
つまり、f(x) の逆関数を計算することが出来れば数列 C の値を高速に計算できると分かります。これはエラトステネスの篩の要領で計算することにより求めることが出来ます。
これで、この問題を解くことが出来ました。計算量は O(ablog(abXY)+clog(cZ)) となり、十分高速だと分かります。