以下、f(x,y,z)=xy mod zとして、一般論について述べた上で、今回のケースへの適用方法を示す。
xとzに共通する素因数をp1,p2,⋯pkとし、z=p1e1p2e2⋯pkeku(ただし、uはp1,p2,⋯pkのいずれとも互いに素な整数)とする。この時、p1e1,p2e2,⋯pkek,uは全て互いに素な整数となるので、f(x,y,z)の値を求める場合、f(x,y,p1e1),f(x,y,p2e2),⋯f(x,y,pkek),f(x,y,u)の値を求めれば良い。
f(x,y,piei) (i=1,2,⋯k)の求め方
xがpiで割れる回数をviとすると、viy≥eiならばf(x,y,piei)=0であり、viy<eiならばf(x,y,piei)=piviyである。
今回の場合、f(a,a↑↑(n−1),piei)を求めれば良い。a↑↑(n−1)の値は多くの場合とてつもなく大きな値になるが、今回の場合はvi⋅a↑↑(n−1)とeiの大小関係さえ分かれば良い。
xiはpiを素因数に持つので、vi≥1である。また、z≥pieiより109≥2eiなので、ei≤log2109=29.8⋯よりei≤29である。よって、vi⋅a↑↑(n−1)<eiならばa↑↑(n−1)<29なので、a↑↑(n−1)≤28となるケースについてのみ考えれば良い。
a↑↑(n−1)≤28となる(a,n)の組は以下の通り。
a | n | a↑↑(n−1) |
---|
任意 | 1 | 0 |
28以下の整数 | 2 | a |
2 | 3 | 4 |
3 | 3 | 27 |
2 | 4 | 16 |
1 | 2以上の整数 | 1 |
よって、これらの組に該当するならばvi⋅a↑↑(n−1)の値を直接計算すれば良い。また、該当しないならばvi⋅a↑↑(n−1)≥eiとなる。
f(x,y,u)の求め方
xとuは互いに素であるから、オイラーの定理よりxφ(u)≡1 (mod u)である。(φ(u)はオイラーのφ関数) よって、y mod φ(u)=wとすると、f(x,y,u)=xw mod uである。
今回の場合はw=a↑↑(n−1) mod φ(u)を求めれば良いので、再帰関数を利用すると良い。以下では、再帰の回数がO(logm)で済むことを示す。
まず、u≤mより、φ(u)≤uであり、
- uが奇数の時、uの素因数分解を∏i=1kpieiとする。(ただし、p1,p2,⋯pkは全て奇数)この時、φ(u)=∏i=1kpiei−1(pi−1)となるため、φ(u)は偶数となる。また、φ(u)<uである。
- uが偶数の時、u以下の偶数は全てuと互いに素でないので、φ(u)≤2uである。
以上より、どんなuについてもφを2回適用すると、その値は半分以下になる。よって、再帰の回数はO(logm)で済む。(出典:アメリカ音ゲーマーぁぁさんのツイート)
また、この問題ではf(x,y,z)を求める際、zの素因数分解がボトルネックとなるので、計算量は2(m+2m+4m+⋯)=O(m)以下となる。よって、制限時間内に間に合う。
解答例は以下の通り。
質問・誤りがある場合
Twitterに連絡ください。ID : @YS55749378